From 922e01018f97b22de0b17c30fbce5884c5526f6e Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Tue, 2 Apr 2024 10:35:30 -0400 Subject: [PATCH 001/128] Started websocket support --- docker/ubuntu/Dockerfile | 2 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docker/ubuntu/Dockerfile b/docker/ubuntu/Dockerfile index 7221661d6..7372a5466 100644 --- a/docker/ubuntu/Dockerfile +++ b/docker/ubuntu/Dockerfile @@ -63,7 +63,7 @@ RUN apt-get update \ rake \ ruby \ && rm -rf /var/lib/apt/lists/* \ - && pip install conan -v 'conan==2.0.9' + && pip install conan # make an agent directory and cd into it WORKDIR /root/agent diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index 93aae58f7..5faa2931e 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -44,6 +44,7 @@ namespace mtconnect::sink::rest_sink { namespace algo = boost::algorithm; namespace sys = boost::system; namespace ssl = boost::asio::ssl; + namespace ws = boost::beast::websocket; using namespace std; using std::placeholders::_1; @@ -196,7 +197,7 @@ namespace mtconnect::sink::rest_sink { auto &msg = m_parser->get(); const auto &remote = beast::get_lowest_layer(derived().stream()).socket().remote_endpoint(); - + // Check for put, post, or delete if (msg.method() != http::verb::get) { @@ -242,6 +243,12 @@ namespace mtconnect::sink::rest_sink { LOG(info) << "ReST Request: From [" << m_request->m_foreignIp << ':' << remote.port() << "]: " << msg.method() << " " << msg.target(); + + // Check if this is a websocket upgrade request. If so, begin a websocket session. + if (ws::is_upgrade(msg)) + { + LOG(debug) << "Upgrading to websocket request"; + } if (!m_dispatch(shared_ptr(), m_request)) { From 233e64c0c5f8d09ea184c5cba3597d06022dc66a Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 5 Apr 2024 21:41:43 -0400 Subject: [PATCH 002/128] updated copyright and added validations --- agent/cppagent.cpp | 2 +- agent_lib/CMakeLists.txt | 7 ++++ src/mtconnect/agent.cpp | 19 +++++++-- src/mtconnect/agent.hpp | 5 ++- src/mtconnect/asset/asset.cpp | 2 +- src/mtconnect/asset/asset.hpp | 2 +- src/mtconnect/asset/asset_buffer.hpp | 2 +- src/mtconnect/asset/asset_storage.hpp | 2 +- .../component_configuration_parameters.cpp | 2 +- .../component_configuration_parameters.hpp | 2 +- src/mtconnect/asset/cutting_tool.cpp | 2 +- src/mtconnect/asset/cutting_tool.hpp | 2 +- src/mtconnect/asset/file_asset.cpp | 2 +- src/mtconnect/asset/file_asset.hpp | 2 +- src/mtconnect/asset/qif_document.cpp | 2 +- src/mtconnect/asset/qif_document.hpp | 2 +- src/mtconnect/asset/raw_material.cpp | 2 +- src/mtconnect/asset/raw_material.hpp | 2 +- src/mtconnect/buffer/checkpoint.cpp | 2 +- src/mtconnect/buffer/checkpoint.hpp | 2 +- src/mtconnect/buffer/circular_buffer.hpp | 2 +- src/mtconnect/config.hpp | 2 +- src/mtconnect/configuration/agent_config.cpp | 5 ++- src/mtconnect/configuration/agent_config.hpp | 2 +- src/mtconnect/configuration/async_context.hpp | 2 +- .../configuration/config_options.hpp | 3 +- src/mtconnect/configuration/hook_manager.hpp | 2 +- src/mtconnect/configuration/parser.cpp | 2 +- src/mtconnect/configuration/parser.hpp | 2 +- src/mtconnect/configuration/service.cpp | 2 +- src/mtconnect/configuration/service.hpp | 2 +- src/mtconnect/device_model/agent_device.cpp | 2 +- src/mtconnect/device_model/agent_device.hpp | 2 +- src/mtconnect/device_model/component.cpp | 2 +- src/mtconnect/device_model/component.hpp | 2 +- src/mtconnect/device_model/composition.cpp | 2 +- src/mtconnect/device_model/composition.hpp | 2 +- .../configuration/configuration.cpp | 2 +- .../configuration/configuration.hpp | 2 +- .../configuration/coordinate_systems.cpp | 2 +- .../configuration/coordinate_systems.hpp | 2 +- .../device_model/configuration/image_file.cpp | 2 +- .../device_model/configuration/image_file.hpp | 2 +- .../device_model/configuration/motion.cpp | 2 +- .../device_model/configuration/motion.hpp | 2 +- .../configuration/relationships.cpp | 2 +- .../configuration/relationships.hpp | 2 +- .../configuration/sensor_configuration.cpp | 2 +- .../configuration/sensor_configuration.hpp | 2 +- .../configuration/solid_model.cpp | 2 +- .../configuration/solid_model.hpp | 2 +- .../configuration/specifications.cpp | 2 +- .../configuration/specifications.hpp | 2 +- .../device_model/data_item/constraints.hpp | 2 +- .../device_model/data_item/data_item.cpp | 2 +- .../device_model/data_item/data_item.hpp | 2 +- .../device_model/data_item/definition.hpp | 2 +- .../device_model/data_item/filter.hpp | 2 +- .../device_model/data_item/relationships.hpp | 2 +- .../device_model/data_item/source.hpp | 2 +- .../data_item/unit_conversion.cpp | 2 +- .../data_item/unit_conversion.hpp | 2 +- src/mtconnect/device_model/description.cpp | 2 +- src/mtconnect/device_model/description.hpp | 2 +- src/mtconnect/device_model/device.cpp | 2 +- src/mtconnect/device_model/device.hpp | 2 +- src/mtconnect/device_model/reference.cpp | 2 +- src/mtconnect/device_model/reference.hpp | 2 +- src/mtconnect/entity/data_set.cpp | 2 +- src/mtconnect/entity/data_set.hpp | 2 +- src/mtconnect/entity/entity.cpp | 2 +- src/mtconnect/entity/entity.hpp | 2 +- src/mtconnect/entity/factory.cpp | 2 +- src/mtconnect/entity/factory.hpp | 2 +- src/mtconnect/entity/json_parser.cpp | 2 +- src/mtconnect/entity/json_parser.hpp | 2 +- src/mtconnect/entity/json_printer.hpp | 2 +- src/mtconnect/entity/qname.hpp | 2 +- src/mtconnect/entity/requirement.cpp | 2 +- src/mtconnect/entity/requirement.hpp | 2 +- src/mtconnect/entity/xml_parser.cpp | 2 +- src/mtconnect/entity/xml_parser.hpp | 2 +- src/mtconnect/entity/xml_printer.cpp | 2 +- src/mtconnect/entity/xml_printer.hpp | 2 +- src/mtconnect/logging.hpp | 2 +- src/mtconnect/mqtt/mqtt_authorization.hpp | 2 +- src/mtconnect/mqtt/mqtt_client.hpp | 2 +- src/mtconnect/mqtt/mqtt_client_impl.hpp | 2 +- src/mtconnect/mqtt/mqtt_server.hpp | 2 +- src/mtconnect/mqtt/mqtt_server_impl.hpp | 2 +- src/mtconnect/observation/change_observer.cpp | 2 +- src/mtconnect/observation/change_observer.hpp | 2 +- src/mtconnect/observation/observation.cpp | 23 ++++++----- src/mtconnect/observation/observation.hpp | 2 +- src/mtconnect/parser/xml_parser.cpp | 2 +- src/mtconnect/parser/xml_parser.hpp | 2 +- src/mtconnect/pipeline/convert_sample.hpp | 2 +- src/mtconnect/pipeline/deliver.cpp | 2 +- src/mtconnect/pipeline/deliver.hpp | 2 +- src/mtconnect/pipeline/delta_filter.hpp | 2 +- src/mtconnect/pipeline/duplicate_filter.hpp | 2 +- src/mtconnect/pipeline/guard.hpp | 2 +- src/mtconnect/pipeline/json_mapper.cpp | 2 +- src/mtconnect/pipeline/json_mapper.hpp | 2 +- src/mtconnect/pipeline/message_mapper.hpp | 2 +- .../pipeline/mtconnect_xml_transform.hpp | 2 +- src/mtconnect/pipeline/period_filter.hpp | 2 +- src/mtconnect/pipeline/pipeline.hpp | 2 +- src/mtconnect/pipeline/pipeline_context.hpp | 2 +- src/mtconnect/pipeline/pipeline_contract.hpp | 2 +- src/mtconnect/pipeline/response_document.cpp | 2 +- src/mtconnect/pipeline/response_document.hpp | 2 +- src/mtconnect/pipeline/shdr_token_mapper.cpp | 2 +- src/mtconnect/pipeline/shdr_token_mapper.hpp | 2 +- src/mtconnect/pipeline/shdr_tokenizer.hpp | 2 +- .../pipeline/timestamp_extractor.hpp | 2 +- src/mtconnect/pipeline/topic_mapper.hpp | 2 +- src/mtconnect/pipeline/transform.hpp | 2 +- src/mtconnect/pipeline/upcase_value.hpp | 2 +- src/mtconnect/printer/json_printer.cpp | 32 +++++++++------ src/mtconnect/printer/json_printer.hpp | 4 +- src/mtconnect/printer/json_printer_helper.hpp | 2 +- src/mtconnect/printer/printer.hpp | 16 ++++++-- src/mtconnect/printer/xml_helper.hpp | 2 +- src/mtconnect/printer/xml_printer.cpp | 7 +++- src/mtconnect/printer/xml_printer.hpp | 4 +- src/mtconnect/printer/xml_printer_helper.hpp | 2 +- src/mtconnect/ruby/embedded.cpp | 2 +- src/mtconnect/ruby/embedded.hpp | 2 +- src/mtconnect/ruby/ruby_agent.hpp | 2 +- src/mtconnect/ruby/ruby_entity.hpp | 2 +- src/mtconnect/ruby/ruby_observation.hpp | 2 +- src/mtconnect/ruby/ruby_pipeline.hpp | 2 +- src/mtconnect/ruby/ruby_smart_ptr.hpp | 2 +- src/mtconnect/ruby/ruby_transform.hpp | 2 +- src/mtconnect/ruby/ruby_type.hpp | 2 +- src/mtconnect/ruby/ruby_vm.hpp | 2 +- src/mtconnect/sink/mqtt_sink/mqtt_service.cpp | 2 +- src/mtconnect/sink/mqtt_sink/mqtt_service.hpp | 2 +- src/mtconnect/sink/rest_sink/cached_file.hpp | 2 +- src/mtconnect/sink/rest_sink/file_cache.cpp | 2 +- src/mtconnect/sink/rest_sink/file_cache.hpp | 2 +- src/mtconnect/sink/rest_sink/parameter.hpp | 2 +- src/mtconnect/sink/rest_sink/request.hpp | 2 +- src/mtconnect/sink/rest_sink/response.hpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.hpp | 2 +- src/mtconnect/sink/rest_sink/routing.hpp | 2 +- src/mtconnect/sink/rest_sink/server.cpp | 2 +- src/mtconnect/sink/rest_sink/server.hpp | 2 +- src/mtconnect/sink/rest_sink/session.hpp | 2 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 2 +- src/mtconnect/sink/rest_sink/session_impl.hpp | 2 +- src/mtconnect/sink/rest_sink/tls_dector.hpp | 2 +- src/mtconnect/sink/sink.cpp | 2 +- src/mtconnect/sink/sink.hpp | 2 +- src/mtconnect/source/adapter/adapter.hpp | 2 +- .../source/adapter/adapter_pipeline.cpp | 2 +- .../source/adapter/adapter_pipeline.hpp | 2 +- .../adapter/agent_adapter/agent_adapter.cpp | 2 +- .../adapter/agent_adapter/agent_adapter.hpp | 2 +- .../adapter/agent_adapter/http_session.hpp | 2 +- .../adapter/agent_adapter/https_session.hpp | 2 +- .../source/adapter/agent_adapter/session.hpp | 2 +- .../adapter/agent_adapter/session_impl.hpp | 2 +- .../adapter/agent_adapter/url_parser.cpp | 2 +- .../adapter/agent_adapter/url_parser.hpp | 2 +- .../source/adapter/mqtt/mqtt_adapter.cpp | 2 +- .../source/adapter/mqtt/mqtt_adapter.hpp | 2 +- .../source/adapter/shdr/connector.cpp | 2 +- .../source/adapter/shdr/connector.hpp | 2 +- .../source/adapter/shdr/shdr_adapter.cpp | 2 +- .../source/adapter/shdr/shdr_adapter.hpp | 2 +- .../source/adapter/shdr/shdr_pipeline.cpp | 2 +- .../source/adapter/shdr/shdr_pipeline.hpp | 2 +- src/mtconnect/source/error_code.hpp | 2 +- src/mtconnect/source/loopback_source.cpp | 2 +- src/mtconnect/source/loopback_source.hpp | 2 +- src/mtconnect/source/source.cpp | 2 +- src/mtconnect/source/source.hpp | 2 +- src/mtconnect/utilities.cpp | 2 +- src/mtconnect/utilities.hpp | 2 +- .../validation/observation_validations.hpp | 39 +++++++++++++++++++ src/mtconnect/validation/observations.cpp | 22 +++++++++++ src/mtconnect/validation/observations.hpp | 29 ++++++++++++++ src/mtconnect/version.cpp | 2 +- test_package/adapter_test.cpp | 2 +- test_package/agent_adapter_test.cpp | 2 +- test_package/agent_device_test.cpp | 2 +- test_package/agent_test.cpp | 2 +- test_package/agent_test_helper.cpp | 2 +- test_package/agent_test_helper.hpp | 2 +- test_package/asset_buffer_test.cpp | 2 +- test_package/asset_hash_test.cpp | 2 +- test_package/asset_test.cpp | 2 +- test_package/change_observer_test.cpp | 2 +- test_package/checkpoint_test.cpp | 2 +- test_package/circular_buffer_test.cpp | 2 +- test_package/component_parameters_test.cpp | 2 +- test_package/component_test.cpp | 2 +- test_package/composition_test.cpp | 2 +- test_package/config_parser_test.cpp | 2 +- test_package/config_test.cpp | 2 +- test_package/connector_test.cpp | 2 +- test_package/coordinate_system_test.cpp | 2 +- test_package/cutting_tool_test.cpp | 2 +- test_package/data_item_mapping_test.cpp | 2 +- test_package/data_item_test.cpp | 2 +- test_package/data_set_test.cpp | 2 +- test_package/device_test.cpp | 2 +- test_package/duplicate_filter_test.cpp | 2 +- test_package/embedded_ruby_test.cpp | 2 +- test_package/entity_parser_test.cpp | 2 +- test_package/entity_printer_test.cpp | 2 +- test_package/entity_test.cpp | 2 +- test_package/file_asset_test.cpp | 2 +- test_package/file_cache_test.cpp | 2 +- test_package/globals_test.cpp | 2 +- test_package/http_server_test.cpp | 2 +- test_package/image_file_test.cpp | 2 +- test_package/json_helper.hpp | 2 +- test_package/json_mapping_test.cpp | 2 +- test_package/json_parser_test.cpp | 2 +- test_package/json_printer_asset_test.cpp | 2 +- test_package/json_printer_error_test.cpp | 2 +- test_package/json_printer_probe_test.cpp | 2 +- test_package/json_printer_stream_test.cpp | 2 +- test_package/json_printer_test.cpp | 2 +- test_package/kinematics_test.cpp | 2 +- test_package/mqtt_adapter_test.cpp | 2 +- test_package/mqtt_isolated_test.cpp | 2 +- test_package/mqtt_sink_2_test.cpp | 2 +- test_package/mqtt_sink_test.cpp | 2 +- test_package/mtconnect_xml_transform_test.cpp | 2 +- test_package/observation_test.cpp | 2 +- test_package/period_filter_test.cpp | 2 +- test_package/pipeline_deliver_test.cpp | 2 +- test_package/pipeline_edit_test.cpp | 2 +- test_package/qif_document_test.cpp | 2 +- test_package/qname_test.cpp | 2 +- test_package/raw_material_test.cpp | 2 +- test_package/references_test.cpp | 2 +- test_package/relationship_test.cpp | 2 +- test_package/response_document_test.cpp | 2 +- test_package/routing_test.cpp | 2 +- test_package/sensor_configuration_test.cpp | 2 +- test_package/shdr_tokenizer_test.cpp | 2 +- test_package/solid_model_test.cpp | 2 +- test_package/specification_test.cpp | 2 +- test_package/table_test.cpp | 2 +- test_package/test_utilities.hpp | 2 +- test_package/testadapter_service.cpp | 2 +- test_package/testadapter_service.hpp | 2 +- test_package/testsink_service.cpp | 2 +- test_package/testsink_service.hpp | 2 +- test_package/timestamp_extractor_test.cpp | 2 +- test_package/tls_http_server_test.cpp | 2 +- test_package/topic_mapping_test.cpp | 2 +- test_package/unit_conversion_test.cpp | 2 +- test_package/url_parser_test.cpp | 2 +- test_package/xml_parser_test.cpp | 2 +- test_package/xml_printer_test.cpp | 2 +- 262 files changed, 424 insertions(+), 287 deletions(-) create mode 100644 src/mtconnect/validation/observation_validations.hpp create mode 100644 src/mtconnect/validation/observations.cpp create mode 100644 src/mtconnect/validation/observations.hpp diff --git a/agent/cppagent.cpp b/agent/cppagent.cpp index ae86382a3..3557e01a4 100644 --- a/agent/cppagent.cpp +++ b/agent/cppagent.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index ac5763e40..975b9fbb5 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -273,6 +273,13 @@ set(AGENT_SOURCES "${SOURCE_DIR}/sink/rest_sink/rest_service.cpp" "${SOURCE_DIR}/sink/rest_sink/server.cpp" "${SOURCE_DIR}/sink/rest_sink/session_impl.cpp" + + # validation HEADER_FILES_ONLY + "${SOURCE_DIR}/validation/observations.hpp" + "${SOURCE_DIR}/validation/observation_validations.hpp" + + # validation SOURCE_FILES_ONLY + "${SOURCE_DIR}/validation/observations.cpp" ) if(WITH_RUBY) diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index 592af871b..a2eaa939c 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -58,6 +58,8 @@ #include "mtconnect/utilities.hpp" #include "mtconnect/version.h" +#include "mtconnect/validation/observations.hpp" + using namespace std; namespace mtconnect { @@ -83,7 +85,8 @@ namespace mtconnect { m_deviceXmlPath(deviceXmlPath), m_circularBuffer(GetOption(options, config::BufferSize).value_or(17), GetOption(options, config::CheckpointFrequency).value_or(1000)), - m_pretty(IsOptionSet(options, mtconnect::configuration::Pretty)) + m_pretty(IsOptionSet(options, mtconnect::configuration::Pretty)), + m_validation(IsOptionSet(options, mtconnect::configuration::Validation)) { using namespace asset; @@ -104,8 +107,8 @@ namespace mtconnect { uint32_t(GetOption(options, mtconnect::configuration::JsonVersion).value_or(2)); // Create the Printers - m_printers["xml"] = make_unique(m_pretty); - m_printers["json"] = make_unique(jsonVersion, m_pretty); + m_printers["xml"] = make_unique(m_pretty, m_validation); + m_printers["json"] = make_unique(jsonVersion, m_pretty, m_validation); if (m_schemaVersion) { @@ -168,6 +171,13 @@ namespace mtconnect { if (!m_observationsInitialized) { + if (m_intSchemaVersion < SCHEMA_VERSION(2, 5) && IsOptionSet(m_options, mtconnect::configuration::Validation)) + { + m_validation = false; + for (auto &printer : m_printers) + printer.second->setValidation(false); + } + for (auto device : m_deviceIndex) initializeDataItems(device); @@ -191,6 +201,7 @@ namespace mtconnect { } m_observationsInitialized = true; + } } diff --git a/src/mtconnect/agent.hpp b/src/mtconnect/agent.hpp index a3202f3c9..e1425dcc9 100644 --- a/src/mtconnect/agent.hpp +++ b/src/mtconnect/agent.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -542,6 +542,9 @@ namespace mtconnect { // For debugging bool m_pretty; + // validation + bool m_validation {false}; + // Agent hooks configuration::HookManager m_beforeInitializeHooks; configuration::HookManager m_afterInitializeHooks; diff --git a/src/mtconnect/asset/asset.cpp b/src/mtconnect/asset/asset.cpp index ecda782de..ac51d0cd9 100644 --- a/src/mtconnect/asset/asset.cpp +++ b/src/mtconnect/asset/asset.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/asset.hpp b/src/mtconnect/asset/asset.hpp index 0fe001a2e..182186c84 100644 --- a/src/mtconnect/asset/asset.hpp +++ b/src/mtconnect/asset/asset.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/asset_buffer.hpp b/src/mtconnect/asset/asset_buffer.hpp index b4aa75bff..662780745 100644 --- a/src/mtconnect/asset/asset_buffer.hpp +++ b/src/mtconnect/asset/asset_buffer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/asset_storage.hpp b/src/mtconnect/asset/asset_storage.hpp index dcccae645..ff90e49a4 100644 --- a/src/mtconnect/asset/asset_storage.hpp +++ b/src/mtconnect/asset/asset_storage.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/component_configuration_parameters.cpp b/src/mtconnect/asset/component_configuration_parameters.cpp index 100652671..d341b6d8c 100644 --- a/src/mtconnect/asset/component_configuration_parameters.cpp +++ b/src/mtconnect/asset/component_configuration_parameters.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/component_configuration_parameters.hpp b/src/mtconnect/asset/component_configuration_parameters.hpp index ef45675fb..fc40d3449 100644 --- a/src/mtconnect/asset/component_configuration_parameters.hpp +++ b/src/mtconnect/asset/component_configuration_parameters.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/cutting_tool.cpp b/src/mtconnect/asset/cutting_tool.cpp index 579350bcb..43d5303af 100644 --- a/src/mtconnect/asset/cutting_tool.cpp +++ b/src/mtconnect/asset/cutting_tool.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/cutting_tool.hpp b/src/mtconnect/asset/cutting_tool.hpp index 1c3e820c9..7eec093e6 100644 --- a/src/mtconnect/asset/cutting_tool.hpp +++ b/src/mtconnect/asset/cutting_tool.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/file_asset.cpp b/src/mtconnect/asset/file_asset.cpp index 222b97f97..b001c86ca 100644 --- a/src/mtconnect/asset/file_asset.cpp +++ b/src/mtconnect/asset/file_asset.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/file_asset.hpp b/src/mtconnect/asset/file_asset.hpp index 380f26bcb..9c5ea9797 100644 --- a/src/mtconnect/asset/file_asset.hpp +++ b/src/mtconnect/asset/file_asset.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/qif_document.cpp b/src/mtconnect/asset/qif_document.cpp index bf7b77913..6c762cd12 100644 --- a/src/mtconnect/asset/qif_document.cpp +++ b/src/mtconnect/asset/qif_document.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/qif_document.hpp b/src/mtconnect/asset/qif_document.hpp index e1c58fcfd..45bc7f2f2 100644 --- a/src/mtconnect/asset/qif_document.hpp +++ b/src/mtconnect/asset/qif_document.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/raw_material.cpp b/src/mtconnect/asset/raw_material.cpp index a9a44d3f3..0ca15b37d 100644 --- a/src/mtconnect/asset/raw_material.cpp +++ b/src/mtconnect/asset/raw_material.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/raw_material.hpp b/src/mtconnect/asset/raw_material.hpp index 2612ed5d8..76af8d858 100644 --- a/src/mtconnect/asset/raw_material.hpp +++ b/src/mtconnect/asset/raw_material.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/buffer/checkpoint.cpp b/src/mtconnect/buffer/checkpoint.cpp index a0e32f6e8..fd5ec3034 100644 --- a/src/mtconnect/buffer/checkpoint.cpp +++ b/src/mtconnect/buffer/checkpoint.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/buffer/checkpoint.hpp b/src/mtconnect/buffer/checkpoint.hpp index 7e7c582a8..b830c223d 100644 --- a/src/mtconnect/buffer/checkpoint.hpp +++ b/src/mtconnect/buffer/checkpoint.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/buffer/circular_buffer.hpp b/src/mtconnect/buffer/circular_buffer.hpp index e9b934ae3..eb3b3f4d6 100644 --- a/src/mtconnect/buffer/circular_buffer.hpp +++ b/src/mtconnect/buffer/circular_buffer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/config.hpp b/src/mtconnect/config.hpp index 219d245d6..a522fe123 100644 --- a/src/mtconnect/config.hpp +++ b/src/mtconnect/config.hpp @@ -1,7 +1,7 @@ #pragma once // -// Copyright Copyright 2009-2022, AMT � The Association For Manufacturing Technology (�AMT�) +// Copyright Copyright 2009-2024, AMT � The Association For Manufacturing Technology (�AMT�) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index 80174ad83..bd1349306 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -789,7 +789,8 @@ namespace mtconnect::configuration { {configuration::TlsVerifyClientCertificate, false}, {configuration::TlsClientCAs, ""s}, {configuration::SuppressIPAddress, false}, - {configuration::AllowPutFrom, ""s}}); + {configuration::AllowPutFrom, ""s}, + {configuration::Validation, false}}); m_workerThreadCount = *GetOption(options, configuration::WorkerThreads); m_monitorFiles = *GetOption(options, configuration::MonitorConfigFiles); diff --git a/src/mtconnect/configuration/agent_config.hpp b/src/mtconnect/configuration/agent_config.hpp index 61b39bbd1..dd68f198f 100644 --- a/src/mtconnect/configuration/agent_config.hpp +++ b/src/mtconnect/configuration/agent_config.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/async_context.hpp b/src/mtconnect/configuration/async_context.hpp index 0446685e0..47b05d2bd 100644 --- a/src/mtconnect/configuration/async_context.hpp +++ b/src/mtconnect/configuration/async_context.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/config_options.hpp b/src/mtconnect/configuration/config_options.hpp index ac5bb2d3c..35f33ce5f 100644 --- a/src/mtconnect/configuration/config_options.hpp +++ b/src/mtconnect/configuration/config_options.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -76,6 +76,7 @@ namespace mtconnect { DECLARE_CONFIGURATION(VersionDeviceXml); DECLARE_CONFIGURATION(EnableSourceDeviceModels); DECLARE_CONFIGURATION(WorkerThreads); + DECLARE_CONFIGURATION(Validation); ///@} /// @name MQTT Configuration diff --git a/src/mtconnect/configuration/hook_manager.hpp b/src/mtconnect/configuration/hook_manager.hpp index 4c62cc041..d831146c8 100644 --- a/src/mtconnect/configuration/hook_manager.hpp +++ b/src/mtconnect/configuration/hook_manager.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/parser.cpp b/src/mtconnect/configuration/parser.cpp index e145441d8..2baeb8e15 100644 --- a/src/mtconnect/configuration/parser.cpp +++ b/src/mtconnect/configuration/parser.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/parser.hpp b/src/mtconnect/configuration/parser.hpp index 63fe41c3f..13d9bb0d8 100644 --- a/src/mtconnect/configuration/parser.hpp +++ b/src/mtconnect/configuration/parser.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/service.cpp b/src/mtconnect/configuration/service.cpp index b9669dba0..58ed30689 100644 --- a/src/mtconnect/configuration/service.cpp +++ b/src/mtconnect/configuration/service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/service.hpp b/src/mtconnect/configuration/service.hpp index b61b67a81..fca63e1e5 100644 --- a/src/mtconnect/configuration/service.hpp +++ b/src/mtconnect/configuration/service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/agent_device.cpp b/src/mtconnect/device_model/agent_device.cpp index ef6df6022..dc2e6c6a9 100644 --- a/src/mtconnect/device_model/agent_device.cpp +++ b/src/mtconnect/device_model/agent_device.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/agent_device.hpp b/src/mtconnect/device_model/agent_device.hpp index 6bbe34558..4b693b5e6 100644 --- a/src/mtconnect/device_model/agent_device.hpp +++ b/src/mtconnect/device_model/agent_device.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/component.cpp b/src/mtconnect/device_model/component.cpp index 4935eddaa..779bccc12 100644 --- a/src/mtconnect/device_model/component.cpp +++ b/src/mtconnect/device_model/component.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/component.hpp b/src/mtconnect/device_model/component.hpp index ca0c09d42..911b7a5ad 100644 --- a/src/mtconnect/device_model/component.hpp +++ b/src/mtconnect/device_model/component.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/composition.cpp b/src/mtconnect/device_model/composition.cpp index 923938b34..40f57cd2a 100644 --- a/src/mtconnect/device_model/composition.cpp +++ b/src/mtconnect/device_model/composition.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/composition.hpp b/src/mtconnect/device_model/composition.hpp index 3ad2046cb..97bdad4c5 100644 --- a/src/mtconnect/device_model/composition.hpp +++ b/src/mtconnect/device_model/composition.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/configuration.cpp b/src/mtconnect/device_model/configuration/configuration.cpp index 4f0a5119f..44cbcaa71 100644 --- a/src/mtconnect/device_model/configuration/configuration.cpp +++ b/src/mtconnect/device_model/configuration/configuration.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/configuration.hpp b/src/mtconnect/device_model/configuration/configuration.hpp index f9f707396..dc01d1f3f 100644 --- a/src/mtconnect/device_model/configuration/configuration.hpp +++ b/src/mtconnect/device_model/configuration/configuration.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/coordinate_systems.cpp b/src/mtconnect/device_model/configuration/coordinate_systems.cpp index d5b96a92c..adc9be6fc 100644 --- a/src/mtconnect/device_model/configuration/coordinate_systems.cpp +++ b/src/mtconnect/device_model/configuration/coordinate_systems.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/coordinate_systems.hpp b/src/mtconnect/device_model/configuration/coordinate_systems.hpp index ea414c33d..8fdc819f3 100644 --- a/src/mtconnect/device_model/configuration/coordinate_systems.hpp +++ b/src/mtconnect/device_model/configuration/coordinate_systems.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/image_file.cpp b/src/mtconnect/device_model/configuration/image_file.cpp index 29d6b9a45..84be05aaa 100644 --- a/src/mtconnect/device_model/configuration/image_file.cpp +++ b/src/mtconnect/device_model/configuration/image_file.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/image_file.hpp b/src/mtconnect/device_model/configuration/image_file.hpp index 32448fbea..6aac7f61c 100644 --- a/src/mtconnect/device_model/configuration/image_file.hpp +++ b/src/mtconnect/device_model/configuration/image_file.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/motion.cpp b/src/mtconnect/device_model/configuration/motion.cpp index a5ecd8188..5a863a440 100644 --- a/src/mtconnect/device_model/configuration/motion.cpp +++ b/src/mtconnect/device_model/configuration/motion.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/motion.hpp b/src/mtconnect/device_model/configuration/motion.hpp index ec73c9c27..1594e309d 100644 --- a/src/mtconnect/device_model/configuration/motion.hpp +++ b/src/mtconnect/device_model/configuration/motion.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/relationships.cpp b/src/mtconnect/device_model/configuration/relationships.cpp index bcfba65c1..a2ed6d78f 100644 --- a/src/mtconnect/device_model/configuration/relationships.cpp +++ b/src/mtconnect/device_model/configuration/relationships.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/relationships.hpp b/src/mtconnect/device_model/configuration/relationships.hpp index 62eeb75ac..c2a6fb462 100644 --- a/src/mtconnect/device_model/configuration/relationships.hpp +++ b/src/mtconnect/device_model/configuration/relationships.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/sensor_configuration.cpp b/src/mtconnect/device_model/configuration/sensor_configuration.cpp index b82abae6c..2bb26ecde 100644 --- a/src/mtconnect/device_model/configuration/sensor_configuration.cpp +++ b/src/mtconnect/device_model/configuration/sensor_configuration.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/sensor_configuration.hpp b/src/mtconnect/device_model/configuration/sensor_configuration.hpp index 8a4c54b5c..8eeb25b64 100644 --- a/src/mtconnect/device_model/configuration/sensor_configuration.hpp +++ b/src/mtconnect/device_model/configuration/sensor_configuration.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/solid_model.cpp b/src/mtconnect/device_model/configuration/solid_model.cpp index e2341a7fa..6c96236b1 100644 --- a/src/mtconnect/device_model/configuration/solid_model.cpp +++ b/src/mtconnect/device_model/configuration/solid_model.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/solid_model.hpp b/src/mtconnect/device_model/configuration/solid_model.hpp index 71d60bcfd..fa406d9a5 100644 --- a/src/mtconnect/device_model/configuration/solid_model.hpp +++ b/src/mtconnect/device_model/configuration/solid_model.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/specifications.cpp b/src/mtconnect/device_model/configuration/specifications.cpp index fe74c894c..a4d55bc0c 100644 --- a/src/mtconnect/device_model/configuration/specifications.cpp +++ b/src/mtconnect/device_model/configuration/specifications.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/specifications.hpp b/src/mtconnect/device_model/configuration/specifications.hpp index 90da6bc3a..226af76a1 100644 --- a/src/mtconnect/device_model/configuration/specifications.hpp +++ b/src/mtconnect/device_model/configuration/specifications.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/constraints.hpp b/src/mtconnect/device_model/data_item/constraints.hpp index e6b919888..21c362955 100644 --- a/src/mtconnect/device_model/data_item/constraints.hpp +++ b/src/mtconnect/device_model/data_item/constraints.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/data_item.cpp b/src/mtconnect/device_model/data_item/data_item.cpp index df8d5c331..f65e22381 100644 --- a/src/mtconnect/device_model/data_item/data_item.cpp +++ b/src/mtconnect/device_model/data_item/data_item.cpp @@ -1,6 +1,6 @@ // // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/data_item.hpp b/src/mtconnect/device_model/data_item/data_item.hpp index 6c4a7803d..1337cd748 100644 --- a/src/mtconnect/device_model/data_item/data_item.hpp +++ b/src/mtconnect/device_model/data_item/data_item.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/definition.hpp b/src/mtconnect/device_model/data_item/definition.hpp index 69a5d0b5c..f1ba7245b 100644 --- a/src/mtconnect/device_model/data_item/definition.hpp +++ b/src/mtconnect/device_model/data_item/definition.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/filter.hpp b/src/mtconnect/device_model/data_item/filter.hpp index 0d32733fe..779f6d3cc 100644 --- a/src/mtconnect/device_model/data_item/filter.hpp +++ b/src/mtconnect/device_model/data_item/filter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/relationships.hpp b/src/mtconnect/device_model/data_item/relationships.hpp index 47bc187da..10c34c8c3 100644 --- a/src/mtconnect/device_model/data_item/relationships.hpp +++ b/src/mtconnect/device_model/data_item/relationships.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/source.hpp b/src/mtconnect/device_model/data_item/source.hpp index 561aaa383..e0895282d 100644 --- a/src/mtconnect/device_model/data_item/source.hpp +++ b/src/mtconnect/device_model/data_item/source.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/unit_conversion.cpp b/src/mtconnect/device_model/data_item/unit_conversion.cpp index 84201a88e..26c853c0c 100644 --- a/src/mtconnect/device_model/data_item/unit_conversion.cpp +++ b/src/mtconnect/device_model/data_item/unit_conversion.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/unit_conversion.hpp b/src/mtconnect/device_model/data_item/unit_conversion.hpp index c20fd5151..068a43aa7 100644 --- a/src/mtconnect/device_model/data_item/unit_conversion.hpp +++ b/src/mtconnect/device_model/data_item/unit_conversion.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/description.cpp b/src/mtconnect/device_model/description.cpp index fe999e94b..9a7c1cb4f 100644 --- a/src/mtconnect/device_model/description.cpp +++ b/src/mtconnect/device_model/description.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/description.hpp b/src/mtconnect/device_model/description.hpp index c6c5059df..8789eba6f 100644 --- a/src/mtconnect/device_model/description.hpp +++ b/src/mtconnect/device_model/description.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/device.cpp b/src/mtconnect/device_model/device.cpp index bdfed3bdd..e427c02b1 100644 --- a/src/mtconnect/device_model/device.cpp +++ b/src/mtconnect/device_model/device.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/device.hpp b/src/mtconnect/device_model/device.hpp index b811fd79c..d4ae2a80c 100644 --- a/src/mtconnect/device_model/device.hpp +++ b/src/mtconnect/device_model/device.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/reference.cpp b/src/mtconnect/device_model/reference.cpp index c58bb23d0..bc48b32fa 100644 --- a/src/mtconnect/device_model/reference.cpp +++ b/src/mtconnect/device_model/reference.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/reference.hpp b/src/mtconnect/device_model/reference.hpp index bb91d55ef..ba9595a5a 100644 --- a/src/mtconnect/device_model/reference.hpp +++ b/src/mtconnect/device_model/reference.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT � The Association For Manufacturing Technology (�AMT�) +// Copyright Copyright 2009-2024, AMT � The Association For Manufacturing Technology (�AMT�) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/data_set.cpp b/src/mtconnect/entity/data_set.cpp index 598d5b811..016f5c302 100644 --- a/src/mtconnect/entity/data_set.cpp +++ b/src/mtconnect/entity/data_set.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/data_set.hpp b/src/mtconnect/entity/data_set.hpp index 1602efb42..0fdaa5983 100644 --- a/src/mtconnect/entity/data_set.hpp +++ b/src/mtconnect/entity/data_set.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/entity.cpp b/src/mtconnect/entity/entity.cpp index 777eb306c..99e0b409c 100644 --- a/src/mtconnect/entity/entity.cpp +++ b/src/mtconnect/entity/entity.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/entity.hpp b/src/mtconnect/entity/entity.hpp index b56eec383..8f45cd319 100644 --- a/src/mtconnect/entity/entity.hpp +++ b/src/mtconnect/entity/entity.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/factory.cpp b/src/mtconnect/entity/factory.cpp index 0d1b24ea6..e763accdd 100644 --- a/src/mtconnect/entity/factory.cpp +++ b/src/mtconnect/entity/factory.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/factory.hpp b/src/mtconnect/entity/factory.hpp index 5b19c0c93..b5e1d411c 100644 --- a/src/mtconnect/entity/factory.hpp +++ b/src/mtconnect/entity/factory.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/json_parser.cpp b/src/mtconnect/entity/json_parser.cpp index 03db5f97c..3976d2fb6 100644 --- a/src/mtconnect/entity/json_parser.cpp +++ b/src/mtconnect/entity/json_parser.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/json_parser.hpp b/src/mtconnect/entity/json_parser.hpp index 90f2bb015..2fa29a0bb 100644 --- a/src/mtconnect/entity/json_parser.hpp +++ b/src/mtconnect/entity/json_parser.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT � The Association For Manufacturing Technology (�AMT�) +// Copyright Copyright 2009-2024, AMT � The Association For Manufacturing Technology (�AMT�) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/json_printer.hpp b/src/mtconnect/entity/json_printer.hpp index 24e9629ad..424b7617c 100644 --- a/src/mtconnect/entity/json_printer.hpp +++ b/src/mtconnect/entity/json_printer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/qname.hpp b/src/mtconnect/entity/qname.hpp index 449708404..c2c5b9eda 100644 --- a/src/mtconnect/entity/qname.hpp +++ b/src/mtconnect/entity/qname.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/requirement.cpp b/src/mtconnect/entity/requirement.cpp index e93c7bccc..854fd7e17 100644 --- a/src/mtconnect/entity/requirement.cpp +++ b/src/mtconnect/entity/requirement.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/requirement.hpp b/src/mtconnect/entity/requirement.hpp index 92c57f343..a4a9832bb 100644 --- a/src/mtconnect/entity/requirement.hpp +++ b/src/mtconnect/entity/requirement.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/xml_parser.cpp b/src/mtconnect/entity/xml_parser.cpp index 8fb2c63f1..9c7a37f78 100644 --- a/src/mtconnect/entity/xml_parser.cpp +++ b/src/mtconnect/entity/xml_parser.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/xml_parser.hpp b/src/mtconnect/entity/xml_parser.hpp index 8e66a5f33..d771dc866 100644 --- a/src/mtconnect/entity/xml_parser.hpp +++ b/src/mtconnect/entity/xml_parser.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/xml_printer.cpp b/src/mtconnect/entity/xml_printer.cpp index 97dd96ab3..799cf2561 100644 --- a/src/mtconnect/entity/xml_printer.cpp +++ b/src/mtconnect/entity/xml_printer.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/xml_printer.hpp b/src/mtconnect/entity/xml_printer.hpp index 9d556bbf7..23a8aa5dd 100644 --- a/src/mtconnect/entity/xml_printer.hpp +++ b/src/mtconnect/entity/xml_printer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/logging.hpp b/src/mtconnect/logging.hpp index 0d21a757e..5e2d613f2 100644 --- a/src/mtconnect/logging.hpp +++ b/src/mtconnect/logging.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/mqtt/mqtt_authorization.hpp b/src/mtconnect/mqtt/mqtt_authorization.hpp index 08105aa27..73c79ace2 100644 --- a/src/mtconnect/mqtt/mqtt_authorization.hpp +++ b/src/mtconnect/mqtt/mqtt_authorization.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/mqtt/mqtt_client.hpp b/src/mtconnect/mqtt/mqtt_client.hpp index d1245848a..70c614045 100644 --- a/src/mtconnect/mqtt/mqtt_client.hpp +++ b/src/mtconnect/mqtt/mqtt_client.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index dc1747d4e..0a20377dd 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/mqtt/mqtt_server.hpp b/src/mtconnect/mqtt/mqtt_server.hpp index 55a0ccf2e..8d38700a9 100644 --- a/src/mtconnect/mqtt/mqtt_server.hpp +++ b/src/mtconnect/mqtt/mqtt_server.hpp @@ -1,5 +1,5 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/mtconnect/mqtt/mqtt_server_impl.hpp b/src/mtconnect/mqtt/mqtt_server_impl.hpp index 13bd773b8..4c3b05715 100644 --- a/src/mtconnect/mqtt/mqtt_server_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_server_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index bdf4143e4..88b5c5da4 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index f08ca61ae..3f4e5c2eb 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/observation/observation.cpp b/src/mtconnect/observation/observation.cpp index 2a6c33dd5..fc8c56282 100644 --- a/src/mtconnect/observation/observation.cpp +++ b/src/mtconnect/observation/observation.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,15 +41,18 @@ namespace mtconnect { static FactoryPtr factory; if (!factory) { - factory = make_shared(Requirements({{"dataItemId", true}, - {"timestamp", ValueType::TIMESTAMP, true}, - {"sequence", false}, - {"subType", false}, - {"name", false}, - {"compositionId", false}}), - [](const std::string &name, Properties &props) -> EntityPtr { - return make_shared(name, props); - }); + factory = make_shared( + Requirements({{"dataItemId", true}, + {"timestamp", ValueType::TIMESTAMP, true}, + {"sequence", false}, + {"subType", false}, + {"name", false}, + {"compositionId", false}, + {"quality", ControlledVocab {"VALID", "INVALID", "UNVERIFIABLE"}, false}, + {"deprecated", ValueType::BOOL, false}}), + [](const std::string &name, Properties &props) -> EntityPtr { + return make_shared(name, props); + }); factory->registerFactory("Events:Message", Message::getFactory()); factory->registerFactory("Events:MessageDiscrete", Message::getFactory()); diff --git a/src/mtconnect/observation/observation.hpp b/src/mtconnect/observation/observation.hpp index ffc0f3d0f..bc2e48537 100644 --- a/src/mtconnect/observation/observation.hpp +++ b/src/mtconnect/observation/observation.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/parser/xml_parser.cpp b/src/mtconnect/parser/xml_parser.cpp index 14b4199ca..6485ecfef 100644 --- a/src/mtconnect/parser/xml_parser.cpp +++ b/src/mtconnect/parser/xml_parser.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/parser/xml_parser.hpp b/src/mtconnect/parser/xml_parser.hpp index eff7ac9cb..e5747c987 100644 --- a/src/mtconnect/parser/xml_parser.hpp +++ b/src/mtconnect/parser/xml_parser.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/convert_sample.hpp b/src/mtconnect/pipeline/convert_sample.hpp index 854109bbb..90dc9e907 100644 --- a/src/mtconnect/pipeline/convert_sample.hpp +++ b/src/mtconnect/pipeline/convert_sample.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/deliver.cpp b/src/mtconnect/pipeline/deliver.cpp index 19f390ea6..bdaa044cb 100644 --- a/src/mtconnect/pipeline/deliver.cpp +++ b/src/mtconnect/pipeline/deliver.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/deliver.hpp b/src/mtconnect/pipeline/deliver.hpp index 47e615b2a..f48b45080 100644 --- a/src/mtconnect/pipeline/deliver.hpp +++ b/src/mtconnect/pipeline/deliver.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/delta_filter.hpp b/src/mtconnect/pipeline/delta_filter.hpp index d84a8084b..313f92e49 100644 --- a/src/mtconnect/pipeline/delta_filter.hpp +++ b/src/mtconnect/pipeline/delta_filter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/duplicate_filter.hpp b/src/mtconnect/pipeline/duplicate_filter.hpp index 21f5e49d1..c9fbf09d0 100644 --- a/src/mtconnect/pipeline/duplicate_filter.hpp +++ b/src/mtconnect/pipeline/duplicate_filter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/guard.hpp b/src/mtconnect/pipeline/guard.hpp index 43bf83a23..98cb89dca 100644 --- a/src/mtconnect/pipeline/guard.hpp +++ b/src/mtconnect/pipeline/guard.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/json_mapper.cpp b/src/mtconnect/pipeline/json_mapper.cpp index b81214d53..7bf8dbc1b 100644 --- a/src/mtconnect/pipeline/json_mapper.cpp +++ b/src/mtconnect/pipeline/json_mapper.cpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/json_mapper.hpp b/src/mtconnect/pipeline/json_mapper.hpp index e2c75dcbb..d437a6b5f 100644 --- a/src/mtconnect/pipeline/json_mapper.hpp +++ b/src/mtconnect/pipeline/json_mapper.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/message_mapper.hpp b/src/mtconnect/pipeline/message_mapper.hpp index 9588e4465..7f84e078a 100644 --- a/src/mtconnect/pipeline/message_mapper.hpp +++ b/src/mtconnect/pipeline/message_mapper.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/mtconnect_xml_transform.hpp b/src/mtconnect/pipeline/mtconnect_xml_transform.hpp index 4236cd467..269913336 100644 --- a/src/mtconnect/pipeline/mtconnect_xml_transform.hpp +++ b/src/mtconnect/pipeline/mtconnect_xml_transform.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/period_filter.hpp b/src/mtconnect/pipeline/period_filter.hpp index 4d2826382..6baf6545e 100644 --- a/src/mtconnect/pipeline/period_filter.hpp +++ b/src/mtconnect/pipeline/period_filter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/pipeline.hpp b/src/mtconnect/pipeline/pipeline.hpp index 1ee849233..c16b9e334 100644 --- a/src/mtconnect/pipeline/pipeline.hpp +++ b/src/mtconnect/pipeline/pipeline.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/pipeline_context.hpp b/src/mtconnect/pipeline/pipeline_context.hpp index bd451f150..42e55b554 100644 --- a/src/mtconnect/pipeline/pipeline_context.hpp +++ b/src/mtconnect/pipeline/pipeline_context.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/pipeline_contract.hpp b/src/mtconnect/pipeline/pipeline_contract.hpp index 4de67eb11..ace303522 100644 --- a/src/mtconnect/pipeline/pipeline_contract.hpp +++ b/src/mtconnect/pipeline/pipeline_contract.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/response_document.cpp b/src/mtconnect/pipeline/response_document.cpp index aaa1b4066..419d4e6eb 100644 --- a/src/mtconnect/pipeline/response_document.cpp +++ b/src/mtconnect/pipeline/response_document.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/response_document.hpp b/src/mtconnect/pipeline/response_document.hpp index 1a915f001..f61016526 100644 --- a/src/mtconnect/pipeline/response_document.hpp +++ b/src/mtconnect/pipeline/response_document.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/shdr_token_mapper.cpp b/src/mtconnect/pipeline/shdr_token_mapper.cpp index 3a65ceabe..a7bc983e2 100644 --- a/src/mtconnect/pipeline/shdr_token_mapper.cpp +++ b/src/mtconnect/pipeline/shdr_token_mapper.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/shdr_token_mapper.hpp b/src/mtconnect/pipeline/shdr_token_mapper.hpp index 23f45a9dc..f12c192d6 100644 --- a/src/mtconnect/pipeline/shdr_token_mapper.hpp +++ b/src/mtconnect/pipeline/shdr_token_mapper.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/shdr_tokenizer.hpp b/src/mtconnect/pipeline/shdr_tokenizer.hpp index 5512d7ca9..a9c3d31f0 100644 --- a/src/mtconnect/pipeline/shdr_tokenizer.hpp +++ b/src/mtconnect/pipeline/shdr_tokenizer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/timestamp_extractor.hpp b/src/mtconnect/pipeline/timestamp_extractor.hpp index 48ceb602f..4164e8fe7 100644 --- a/src/mtconnect/pipeline/timestamp_extractor.hpp +++ b/src/mtconnect/pipeline/timestamp_extractor.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/topic_mapper.hpp b/src/mtconnect/pipeline/topic_mapper.hpp index 3d0067713..7aa52887e 100644 --- a/src/mtconnect/pipeline/topic_mapper.hpp +++ b/src/mtconnect/pipeline/topic_mapper.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/transform.hpp b/src/mtconnect/pipeline/transform.hpp index 917237bc3..6fbf9d3a5 100644 --- a/src/mtconnect/pipeline/transform.hpp +++ b/src/mtconnect/pipeline/transform.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/upcase_value.hpp b/src/mtconnect/pipeline/upcase_value.hpp index b95bb24ad..fae0d1a42 100644 --- a/src/mtconnect/pipeline/upcase_value.hpp +++ b/src/mtconnect/pipeline/upcase_value.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/printer/json_printer.cpp b/src/mtconnect/printer/json_printer.cpp index 1108d0878..2720d5eaa 100644 --- a/src/mtconnect/printer/json_printer.cpp +++ b/src/mtconnect/printer/json_printer.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -47,8 +47,8 @@ namespace mtconnect::printer { using namespace device_model; using namespace rapidjson; - JsonPrinter::JsonPrinter(uint32_t jsonVersion, bool pretty) - : Printer(pretty), m_jsonVersion(jsonVersion) + JsonPrinter::JsonPrinter(uint32_t jsonVersion, bool pretty, bool validation) + : Printer(pretty, validation), m_jsonVersion(jsonVersion) { NAMED_SCOPE("JsonPrinter::JsonPrinter"); char appVersion[32] = {0}; @@ -60,7 +60,8 @@ namespace mtconnect::printer { template inline void header(AutoJsonObject &obj, const string &version, const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, - const string &schemaVersion, const string modelChangeTime) + const string &schemaVersion, const string modelChangeTime, + bool validation) { obj.AddPairs("version", version, "creationTime", getCurrentTime(GMT), "testIndicator", false, "instanceId", instanceId, "sender", hostname, "schemaVersion", schemaVersion); @@ -69,6 +70,9 @@ namespace mtconnect::printer { obj.AddPairs("deviceModelChangeTime", modelChangeTime); if (bufferSize > 0) obj.AddPairs("bufferSize", bufferSize); + if (validation) + obj.AddPairs("validation", true); + } template @@ -76,9 +80,10 @@ namespace mtconnect::printer { const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetBufferSize, const unsigned int assetCount, const string &schemaVersion, - const string modelChangeTime) + const string modelChangeTime, + const bool validation) { - header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime); + header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, validation); obj.AddPairs("assetBufferSize", assetBufferSize, "assetCount", assetCount); } @@ -87,9 +92,10 @@ namespace mtconnect::printer { const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSequence, const uint64_t firstSequence, const uint64_t lastSequence, const string &schemaVersion, - const string modelChangeTime) + const string modelChangeTime, + const bool validation) { - header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime); + header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, validation); obj.AddPairs("nextSequence", nextSequence, "lastSequence", lastSequence, "firstSequence", firstSequence); } @@ -123,7 +129,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); header(obj, m_version, m_senderName, instanceId, bufferSize, *m_schemaVersion, - m_modelChangeTime); + m_modelChangeTime, m_validation); } { if (m_jsonVersion > 1) @@ -180,7 +186,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); probeAssetHeader(obj, m_version, m_senderName, instanceId, bufferSize, assetBufferSize, - assetCount, *m_schemaVersion, m_modelChangeTime); + assetCount, *m_schemaVersion, m_modelChangeTime, m_validation); } { obj.Key("Devices"); @@ -207,7 +213,8 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); probeAssetHeader(obj, m_version, m_senderName, instanceId, 0, bufferSize, assetCount, - *m_schemaVersion, m_modelChangeTime); + *m_schemaVersion, m_modelChangeTime, + m_validation); } { obj.Key("Assets"); @@ -405,7 +412,8 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); streamHeader(obj, m_version, m_senderName, instanceId, bufferSize, nextSeq, firstSeq, - lastSeq, *m_schemaVersion, m_modelChangeTime); + lastSeq, *m_schemaVersion, m_modelChangeTime, + m_validation); } { diff --git a/src/mtconnect/printer/json_printer.hpp b/src/mtconnect/printer/json_printer.hpp index 2a1e4ea96..fd392133a 100644 --- a/src/mtconnect/printer/json_printer.hpp +++ b/src/mtconnect/printer/json_printer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,7 +27,7 @@ namespace mtconnect::printer { class AGENT_LIB_API JsonPrinter : public Printer { public: - JsonPrinter(uint32_t jsonVersion, bool pretty = false); + JsonPrinter(uint32_t jsonVersion, bool pretty = false, bool validation = false); ~JsonPrinter() override = default; std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, diff --git a/src/mtconnect/printer/json_printer_helper.hpp b/src/mtconnect/printer/json_printer_helper.hpp index e8bb39b00..61b843e33 100644 --- a/src/mtconnect/printer/json_printer_helper.hpp +++ b/src/mtconnect/printer/json_printer_helper.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/printer/printer.hpp b/src/mtconnect/printer/printer.hpp index cfc0bd270..4e39cb0a8 100644 --- a/src/mtconnect/printer/printer.hpp +++ b/src/mtconnect/printer/printer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,7 +49,7 @@ namespace mtconnect { public: /// @brief construct a printer /// @param pretty `true` if content should be pretty printed - Printer(bool pretty = false) : m_pretty(pretty) {} + Printer(bool pretty = false, bool validation = false) : m_pretty(pretty), m_validation(validation) {} virtual ~Printer() = default; /// @brief Generate an MTConnect Error document @@ -145,9 +145,19 @@ namespace mtconnect { const_cast(this)->m_schemaVersion.emplace(ver); } } + + /// @brief Get validation header flag state + /// @returns validation state + bool getValidation() const { return m_validation; } + + /// @brief sets validation state + /// @param validation the validation state + void setValidation(bool v) { m_validation = v; } + protected: - bool m_pretty; + bool m_pretty; //< Turns pretty printing on + bool m_validation; //< Sets validation flag in header std::string m_modelChangeTime; std::optional m_schemaVersion; std::string m_senderName {"localhost"}; diff --git a/src/mtconnect/printer/xml_helper.hpp b/src/mtconnect/printer/xml_helper.hpp index 94eac2d27..e1758ae55 100644 --- a/src/mtconnect/printer/xml_helper.hpp +++ b/src/mtconnect/printer/xml_helper.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/printer/xml_printer.cpp b/src/mtconnect/printer/xml_printer.cpp index 915193d66..5e0aa1b2e 100644 --- a/src/mtconnect/printer/xml_printer.cpp +++ b/src/mtconnect/printer/xml_printer.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -100,7 +100,7 @@ namespace mtconnect::printer { xmlBufferPtr m_buf; }; - XmlPrinter::XmlPrinter(bool pretty) : Printer(pretty) { NAMED_SCOPE("xml.printer"); } + XmlPrinter::XmlPrinter(bool pretty, bool validation) : Printer(pretty, validation) { NAMED_SCOPE("xml.printer"); } void XmlPrinter::addDevicesNamespace(const std::string &urn, const std::string &location, const std::string &prefix) @@ -636,6 +636,9 @@ namespace mtconnect::printer { addAttribute(writer, "sender", m_senderName); addAttribute(writer, "instanceId", to_string(instanceId)); + + if (m_validation) + addAttribute(writer, "instanceId", "true"s); char version[32] = {0}; sprintf(version, "%d.%d.%d.%d", AGENT_VERSION_MAJOR, AGENT_VERSION_MINOR, AGENT_VERSION_PATCH, diff --git a/src/mtconnect/printer/xml_printer.hpp b/src/mtconnect/printer/xml_printer.hpp index bb4e0c2df..781a297cb 100644 --- a/src/mtconnect/printer/xml_printer.hpp +++ b/src/mtconnect/printer/xml_printer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,7 +40,7 @@ namespace mtconnect { class AGENT_LIB_API XmlPrinter : public Printer { public: - XmlPrinter(bool pretty = false); + XmlPrinter(bool pretty = false, bool validation = false); ~XmlPrinter() override = default; std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, diff --git a/src/mtconnect/printer/xml_printer_helper.hpp b/src/mtconnect/printer/xml_printer_helper.hpp index 64eab3aa1..3ac60e91a 100644 --- a/src/mtconnect/printer/xml_printer_helper.hpp +++ b/src/mtconnect/printer/xml_printer_helper.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/embedded.cpp b/src/mtconnect/ruby/embedded.cpp index 6c5538cc8..4942b6885 100644 --- a/src/mtconnect/ruby/embedded.cpp +++ b/src/mtconnect/ruby/embedded.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/embedded.hpp b/src/mtconnect/ruby/embedded.hpp index 7caec3103..38a5a1102 100644 --- a/src/mtconnect/ruby/embedded.hpp +++ b/src/mtconnect/ruby/embedded.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_agent.hpp b/src/mtconnect/ruby/ruby_agent.hpp index 00da26c58..954fff2da 100644 --- a/src/mtconnect/ruby/ruby_agent.hpp +++ b/src/mtconnect/ruby/ruby_agent.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_entity.hpp b/src/mtconnect/ruby/ruby_entity.hpp index 6ba905097..6302afe4d 100644 --- a/src/mtconnect/ruby/ruby_entity.hpp +++ b/src/mtconnect/ruby/ruby_entity.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_observation.hpp b/src/mtconnect/ruby/ruby_observation.hpp index a41586214..df0dec968 100644 --- a/src/mtconnect/ruby/ruby_observation.hpp +++ b/src/mtconnect/ruby/ruby_observation.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_pipeline.hpp b/src/mtconnect/ruby/ruby_pipeline.hpp index beb10a3c4..0e1bf5312 100644 --- a/src/mtconnect/ruby/ruby_pipeline.hpp +++ b/src/mtconnect/ruby/ruby_pipeline.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_smart_ptr.hpp b/src/mtconnect/ruby/ruby_smart_ptr.hpp index 97e34f3d3..a8c23106f 100644 --- a/src/mtconnect/ruby/ruby_smart_ptr.hpp +++ b/src/mtconnect/ruby/ruby_smart_ptr.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_transform.hpp b/src/mtconnect/ruby/ruby_transform.hpp index 4dc9c4cdf..94693b29d 100644 --- a/src/mtconnect/ruby/ruby_transform.hpp +++ b/src/mtconnect/ruby/ruby_transform.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_type.hpp b/src/mtconnect/ruby/ruby_type.hpp index 34641cd3b..087b0e8fd 100644 --- a/src/mtconnect/ruby/ruby_type.hpp +++ b/src/mtconnect/ruby/ruby_type.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_vm.hpp b/src/mtconnect/ruby/ruby_vm.hpp index d33134ba9..39267a2e2 100644 --- a/src/mtconnect/ruby/ruby_vm.hpp +++ b/src/mtconnect/ruby/ruby_vm.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp index 6a2f54e59..b28b72d0f 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp index 3b89b2cea..e94d01f55 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/cached_file.hpp b/src/mtconnect/sink/rest_sink/cached_file.hpp index da2ca52f5..40efea4fb 100644 --- a/src/mtconnect/sink/rest_sink/cached_file.hpp +++ b/src/mtconnect/sink/rest_sink/cached_file.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/file_cache.cpp b/src/mtconnect/sink/rest_sink/file_cache.cpp index d230a490e..07d31e182 100644 --- a/src/mtconnect/sink/rest_sink/file_cache.cpp +++ b/src/mtconnect/sink/rest_sink/file_cache.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/file_cache.hpp b/src/mtconnect/sink/rest_sink/file_cache.hpp index 5ee445a7c..f5125ccd3 100644 --- a/src/mtconnect/sink/rest_sink/file_cache.hpp +++ b/src/mtconnect/sink/rest_sink/file_cache.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/parameter.hpp b/src/mtconnect/sink/rest_sink/parameter.hpp index 9eea8feeb..cb2879c34 100644 --- a/src/mtconnect/sink/rest_sink/parameter.hpp +++ b/src/mtconnect/sink/rest_sink/parameter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index f62f37dbe..ebff06028 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/response.hpp b/src/mtconnect/sink/rest_sink/response.hpp index f8ae3c98e..a67bdbe6b 100644 --- a/src/mtconnect/sink/rest_sink/response.hpp +++ b/src/mtconnect/sink/rest_sink/response.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 6e123ed84..9237a4645 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/rest_service.hpp b/src/mtconnect/sink/rest_sink/rest_service.hpp index 3e8091cb0..51505fd51 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.hpp +++ b/src/mtconnect/sink/rest_sink/rest_service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index 10d852a98..ca8bdf38d 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/server.cpp b/src/mtconnect/sink/rest_sink/server.cpp index 93b387e1f..7071c02ee 100644 --- a/src/mtconnect/sink/rest_sink/server.cpp +++ b/src/mtconnect/sink/rest_sink/server.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/server.hpp b/src/mtconnect/sink/rest_sink/server.hpp index 07c5c4b59..d72fd1764 100644 --- a/src/mtconnect/sink/rest_sink/server.hpp +++ b/src/mtconnect/sink/rest_sink/server.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index a6443f782..c4ed9041a 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index 93aae58f7..43b3cbdea 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/session_impl.hpp b/src/mtconnect/sink/rest_sink/session_impl.hpp index 404d25b9c..539c3ece3 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.hpp +++ b/src/mtconnect/sink/rest_sink/session_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/tls_dector.hpp b/src/mtconnect/sink/rest_sink/tls_dector.hpp index 197e9a91b..cf8065899 100644 --- a/src/mtconnect/sink/rest_sink/tls_dector.hpp +++ b/src/mtconnect/sink/rest_sink/tls_dector.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/sink.cpp b/src/mtconnect/sink/sink.cpp index 4fb757485..1a65d10f9 100644 --- a/src/mtconnect/sink/sink.cpp +++ b/src/mtconnect/sink/sink.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/sink.hpp b/src/mtconnect/sink/sink.hpp index 1e517284d..c06d0e1c4 100644 --- a/src/mtconnect/sink/sink.hpp +++ b/src/mtconnect/sink/sink.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/adapter.hpp b/src/mtconnect/source/adapter/adapter.hpp index f27ffc03a..7052d6d87 100644 --- a/src/mtconnect/source/adapter/adapter.hpp +++ b/src/mtconnect/source/adapter/adapter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/adapter_pipeline.cpp b/src/mtconnect/source/adapter/adapter_pipeline.cpp index 741cabdfb..16a3dd505 100644 --- a/src/mtconnect/source/adapter/adapter_pipeline.cpp +++ b/src/mtconnect/source/adapter/adapter_pipeline.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/adapter_pipeline.hpp b/src/mtconnect/source/adapter/adapter_pipeline.hpp index 3d6155d8e..a21ac3ce3 100644 --- a/src/mtconnect/source/adapter/adapter_pipeline.hpp +++ b/src/mtconnect/source/adapter/adapter_pipeline.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/agent_adapter.cpp b/src/mtconnect/source/adapter/agent_adapter/agent_adapter.cpp index a38db70a3..8845bbed3 100644 --- a/src/mtconnect/source/adapter/agent_adapter/agent_adapter.cpp +++ b/src/mtconnect/source/adapter/agent_adapter/agent_adapter.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/agent_adapter.hpp b/src/mtconnect/source/adapter/agent_adapter/agent_adapter.hpp index e949654ac..b7c608005 100644 --- a/src/mtconnect/source/adapter/agent_adapter/agent_adapter.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/agent_adapter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/http_session.hpp b/src/mtconnect/source/adapter/agent_adapter/http_session.hpp index 1003a2cd1..2bb063647 100644 --- a/src/mtconnect/source/adapter/agent_adapter/http_session.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/http_session.hpp @@ -1,6 +1,6 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/https_session.hpp b/src/mtconnect/source/adapter/agent_adapter/https_session.hpp index 0b5b0ad34..4875b06c2 100644 --- a/src/mtconnect/source/adapter/agent_adapter/https_session.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/https_session.hpp @@ -1,6 +1,6 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/session.hpp b/src/mtconnect/source/adapter/agent_adapter/session.hpp index 89e146829..5edf96986 100644 --- a/src/mtconnect/source/adapter/agent_adapter/session.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/session.hpp @@ -1,6 +1,6 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/session_impl.hpp b/src/mtconnect/source/adapter/agent_adapter/session_impl.hpp index 43ff13e54..3cfba36d8 100644 --- a/src/mtconnect/source/adapter/agent_adapter/session_impl.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/session_impl.hpp @@ -1,6 +1,6 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/url_parser.cpp b/src/mtconnect/source/adapter/agent_adapter/url_parser.cpp index b6c3bb17d..1932cd944 100644 --- a/src/mtconnect/source/adapter/agent_adapter/url_parser.cpp +++ b/src/mtconnect/source/adapter/agent_adapter/url_parser.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/url_parser.hpp b/src/mtconnect/source/adapter/agent_adapter/url_parser.hpp index b14fd0da0..62e1300c7 100644 --- a/src/mtconnect/source/adapter/agent_adapter/url_parser.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/url_parser.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp index de1399a03..e673a97ea 100644 --- a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp +++ b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.hpp b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.hpp index 6d017ad05..66e2554ab 100644 --- a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.hpp +++ b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/connector.cpp b/src/mtconnect/source/adapter/shdr/connector.cpp index 216d4c894..fb7f5979d 100644 --- a/src/mtconnect/source/adapter/shdr/connector.cpp +++ b/src/mtconnect/source/adapter/shdr/connector.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/connector.hpp b/src/mtconnect/source/adapter/shdr/connector.hpp index 638c0e9dc..d8cd727a8 100644 --- a/src/mtconnect/source/adapter/shdr/connector.hpp +++ b/src/mtconnect/source/adapter/shdr/connector.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp b/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp index d3c685ab2..a96e27c53 100644 --- a/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp +++ b/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/shdr_adapter.hpp b/src/mtconnect/source/adapter/shdr/shdr_adapter.hpp index d04519a26..4b40f514c 100644 --- a/src/mtconnect/source/adapter/shdr/shdr_adapter.hpp +++ b/src/mtconnect/source/adapter/shdr/shdr_adapter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/shdr_pipeline.cpp b/src/mtconnect/source/adapter/shdr/shdr_pipeline.cpp index 2a2f6d55a..45116061e 100644 --- a/src/mtconnect/source/adapter/shdr/shdr_pipeline.cpp +++ b/src/mtconnect/source/adapter/shdr/shdr_pipeline.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/shdr_pipeline.hpp b/src/mtconnect/source/adapter/shdr/shdr_pipeline.hpp index 5962834f1..f975ee4f2 100644 --- a/src/mtconnect/source/adapter/shdr/shdr_pipeline.hpp +++ b/src/mtconnect/source/adapter/shdr/shdr_pipeline.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/error_code.hpp b/src/mtconnect/source/error_code.hpp index 32f7b4bd2..af3164bb5 100644 --- a/src/mtconnect/source/error_code.hpp +++ b/src/mtconnect/source/error_code.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/loopback_source.cpp b/src/mtconnect/source/loopback_source.cpp index 9befdcf16..6cfbcdc6a 100644 --- a/src/mtconnect/source/loopback_source.cpp +++ b/src/mtconnect/source/loopback_source.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/loopback_source.hpp b/src/mtconnect/source/loopback_source.hpp index cd396e041..42734c076 100644 --- a/src/mtconnect/source/loopback_source.hpp +++ b/src/mtconnect/source/loopback_source.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/source.cpp b/src/mtconnect/source/source.cpp index 5cc0322c3..eb1f8c59a 100644 --- a/src/mtconnect/source/source.cpp +++ b/src/mtconnect/source/source.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/source.hpp b/src/mtconnect/source/source.hpp index cdacfb9f5..4debdafb6 100644 --- a/src/mtconnect/source/source.hpp +++ b/src/mtconnect/source/source.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/utilities.cpp b/src/mtconnect/utilities.cpp index 898daf409..e36bd2f53 100644 --- a/src/mtconnect/utilities.cpp +++ b/src/mtconnect/utilities.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/utilities.hpp b/src/mtconnect/utilities.hpp index 8f668b443..87e0110ad 100644 --- a/src/mtconnect/utilities.hpp +++ b/src/mtconnect/utilities.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp new file mode 100644 index 000000000..24af87c85 --- /dev/null +++ b/src/mtconnect/validation/observation_validations.hpp @@ -0,0 +1,39 @@ + Validation ControlledVocabularies { + {"ACTUATOR_STATE", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"AVAILABILITY", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, + {"AXIS_COUPLING", {{"TANDEM", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}, {"SLAVE", 0}}}, + {"AXIS_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"AXIS_STATE", {{"HOME", 0}, {"TRAVEL", 0}, {"PARKED", 0}, {"STOPPED", 0}}}, + {"CHUCK_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"CHUCK_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, + {"CONTROLLER_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"EDIT", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, + {"CONTROLLER_MODE_OVERRIDE", {{"ON", 0}, {"OFF", 0}}}, + {"DIRECTION", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, + {"DOOR_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, + {"EMERGENCY_STOP", {{"ARMED", 0}, {"TRIGGERED", 0}}}, + {"END_OF_BAR", {{"YES", 0}, {"NO", 0}}}, + {"EQUIPMENT_MODE", {{"ON", 0}, {"OFF", 0}}}, + {"EXECUTION", {{"READY", 0}, {"ACTIVE", 0}, {"INTERRUPTED", 0}, {"FEED_HOLD", 0}, {"STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"PROGRAM_STOPPED", 0}, {"PROGRAM_COMPLETED", 0}, {"WAIT", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, + {"FUNCTIONAL_MODE", {{"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}, {"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}}}, + {"PART_DETECT", {{"PRESENT", 0}, {"NOT_PRESENT", 0}}}, + {"PATH_MODE", {{"INDEPENDENT", 0}, {"MASTER", 0}, {"SYNCHRONOUS", 0}, {"MIRROR", 0}}}, + {"POWER_STATE", {{"ON", 0}, {"OFF", 0}}}, + {"POWER_STATUS", {{"ON", SCHEMA_VERSION(1, 1)}, {"OFF", SCHEMA_VERSION(1, 1)}}}, + {"PROGRAM_EDIT", {{"ACTIVE", 0}, {"READY", 0}, {"NOT_READY", 0}}}, + {"PROGRAM_LOCATION_TYPE", {{"LOCAL", 0}, {"EXTERNAL", 0}}}, + {"ROTARY_MODE", {{"SPINDLE", 0}, {"INDEX", 0}, {"CONTOUR", 0}}}, + {"SPINDLE_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"WAIT_STATE", {{"POWERING_UP", 0}, {"POWERING_DOWN", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}, {"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"SECONDARY_PROCESS", 0}, {"PAUSING", 0}, {"RESUMING", 0}}}, + {"PART_STATUS", {{"PASS", 0}, {"FAIL", 0}}}, + {"CONNECTION_STATUS", {{"CLOSED", 0}, {"LISTEN", 0}, {"ESTABLISHED", 0}}}, + {"PART_PROCESSING_STATE", {{"NEEDS_PROCESSING", 0}, {"IN_PROCESS", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"WAITING_FOR_TRANSIT", 0}, {"IN_TRANSIT", 0}, {"TRANSIT_COMPLETE", 0}}}, + {"PROCESS_STATE", {{"INITIALIZING", 0}, {"READY", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INTERRUPTED", 0}, {"ABORTED", 0}}}, + {"VALVE_STATE", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, + {"LOCK_STATE", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, + {"OPERATING_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, + {"PART_COUNT_TYPE", {{"EACH", 0}, {"BATCH", 0}}}, + {"LEAK_DETECT", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, + {"BATTERY_STATE", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGING", 0}, {"DISCHARGED", 0}}}, + {"ADAPTER_URI", {{"PASS", 0}, {"FAIL", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"UNDEFINED", 0}}}, + {"UNCERTAINTY_TYPE", {{"COMBINED", 0}, {"MEAN", 0}}} + }; diff --git a/src/mtconnect/validation/observations.cpp b/src/mtconnect/validation/observations.cpp new file mode 100644 index 000000000..4f2825a5d --- /dev/null +++ b/src/mtconnect/validation/observations.cpp @@ -0,0 +1,22 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "observations.hpp" + +namespace mtconnect::validation::observations { +#include "observation_validations.hpp" +} diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp new file mode 100644 index 000000000..f540d6131 --- /dev/null +++ b/src/mtconnect/validation/observations.hpp @@ -0,0 +1,29 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include "../utilities.hpp" + +#include +#include + +namespace mtconnect::validation::observations { + using Validation = std::unordered_map>; + + extern Validation ControlledVocabularies; +} diff --git a/src/mtconnect/version.cpp b/src/mtconnect/version.cpp index b27f769f2..8a082fb36 100644 --- a/src/mtconnect/version.cpp +++ b/src/mtconnect/version.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/adapter_test.cpp b/test_package/adapter_test.cpp index 8fa5eba8b..58712ec98 100644 --- a/test_package/adapter_test.cpp +++ b/test_package/adapter_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/agent_adapter_test.cpp b/test_package/agent_adapter_test.cpp index 2942befa8..807e366e2 100644 --- a/test_package/agent_adapter_test.cpp +++ b/test_package/agent_adapter_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/agent_device_test.cpp b/test_package/agent_device_test.cpp index 02a131dfa..da174ed81 100644 --- a/test_package/agent_device_test.cpp +++ b/test_package/agent_device_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index b4d441553..d7b673f84 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/agent_test_helper.cpp b/test_package/agent_test_helper.cpp index 8cc85fba0..c1dd2ccb3 100644 --- a/test_package/agent_test_helper.cpp +++ b/test_package/agent_test_helper.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/agent_test_helper.hpp b/test_package/agent_test_helper.hpp index 39c857883..13c14fc94 100644 --- a/test_package/agent_test_helper.hpp +++ b/test_package/agent_test_helper.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/asset_buffer_test.cpp b/test_package/asset_buffer_test.cpp index 54d5c4076..92efefea8 100644 --- a/test_package/asset_buffer_test.cpp +++ b/test_package/asset_buffer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/asset_hash_test.cpp b/test_package/asset_hash_test.cpp index 6d5529e48..ae17a1665 100644 --- a/test_package/asset_hash_test.cpp +++ b/test_package/asset_hash_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/asset_test.cpp b/test_package/asset_test.cpp index 49e383f31..f5fd92825 100644 --- a/test_package/asset_test.cpp +++ b/test_package/asset_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/change_observer_test.cpp b/test_package/change_observer_test.cpp index e3f90663a..b7501a6c8 100644 --- a/test_package/change_observer_test.cpp +++ b/test_package/change_observer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/checkpoint_test.cpp b/test_package/checkpoint_test.cpp index e810b8d31..f874ae5c4 100644 --- a/test_package/checkpoint_test.cpp +++ b/test_package/checkpoint_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/circular_buffer_test.cpp b/test_package/circular_buffer_test.cpp index ca19a6ea2..4e935c94b 100644 --- a/test_package/circular_buffer_test.cpp +++ b/test_package/circular_buffer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/component_parameters_test.cpp b/test_package/component_parameters_test.cpp index 6df0c76db..076175db9 100644 --- a/test_package/component_parameters_test.cpp +++ b/test_package/component_parameters_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/component_test.cpp b/test_package/component_test.cpp index 53c8c583c..b4b8c1a87 100644 --- a/test_package/component_test.cpp +++ b/test_package/component_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/composition_test.cpp b/test_package/composition_test.cpp index b9e75879b..4501ac3f4 100644 --- a/test_package/composition_test.cpp +++ b/test_package/composition_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/config_parser_test.cpp b/test_package/config_parser_test.cpp index 2bc8f9872..fab7e9ad6 100644 --- a/test_package/config_parser_test.cpp +++ b/test_package/config_parser_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/config_test.cpp b/test_package/config_test.cpp index 296931c9f..b4cf02da3 100644 --- a/test_package/config_test.cpp +++ b/test_package/config_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/connector_test.cpp b/test_package/connector_test.cpp index 480179032..e40c351d8 100644 --- a/test_package/connector_test.cpp +++ b/test_package/connector_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/coordinate_system_test.cpp b/test_package/coordinate_system_test.cpp index 3b9c380a0..4a4f56535 100644 --- a/test_package/coordinate_system_test.cpp +++ b/test_package/coordinate_system_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/cutting_tool_test.cpp b/test_package/cutting_tool_test.cpp index 5f1c04ef1..4647cc036 100644 --- a/test_package/cutting_tool_test.cpp +++ b/test_package/cutting_tool_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/data_item_mapping_test.cpp b/test_package/data_item_mapping_test.cpp index 4a6c983d0..f36ed7399 100644 --- a/test_package/data_item_mapping_test.cpp +++ b/test_package/data_item_mapping_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/data_item_test.cpp b/test_package/data_item_test.cpp index 178bb1ca0..5e88dc6f1 100644 --- a/test_package/data_item_test.cpp +++ b/test_package/data_item_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/data_set_test.cpp b/test_package/data_set_test.cpp index 4c2fd43c6..24566788a 100644 --- a/test_package/data_set_test.cpp +++ b/test_package/data_set_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/device_test.cpp b/test_package/device_test.cpp index a0a728922..6bb14a651 100644 --- a/test_package/device_test.cpp +++ b/test_package/device_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/duplicate_filter_test.cpp b/test_package/duplicate_filter_test.cpp index a9b1de3f3..459c50de8 100644 --- a/test_package/duplicate_filter_test.cpp +++ b/test_package/duplicate_filter_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/embedded_ruby_test.cpp b/test_package/embedded_ruby_test.cpp index b12e36b59..c60dc141d 100644 --- a/test_package/embedded_ruby_test.cpp +++ b/test_package/embedded_ruby_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/entity_parser_test.cpp b/test_package/entity_parser_test.cpp index c34a84858..ab752021d 100644 --- a/test_package/entity_parser_test.cpp +++ b/test_package/entity_parser_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/entity_printer_test.cpp b/test_package/entity_printer_test.cpp index 22dd514b9..2999fe1e3 100644 --- a/test_package/entity_printer_test.cpp +++ b/test_package/entity_printer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/entity_test.cpp b/test_package/entity_test.cpp index f10318fd5..88396d8de 100644 --- a/test_package/entity_test.cpp +++ b/test_package/entity_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/file_asset_test.cpp b/test_package/file_asset_test.cpp index a2d57c932..9b5a753e9 100644 --- a/test_package/file_asset_test.cpp +++ b/test_package/file_asset_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/file_cache_test.cpp b/test_package/file_cache_test.cpp index 6d453f781..5e916fd28 100644 --- a/test_package/file_cache_test.cpp +++ b/test_package/file_cache_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/globals_test.cpp b/test_package/globals_test.cpp index 23c423393..48cdee99a 100644 --- a/test_package/globals_test.cpp +++ b/test_package/globals_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/http_server_test.cpp b/test_package/http_server_test.cpp index 07d69fb67..da52c633a 100644 --- a/test_package/http_server_test.cpp +++ b/test_package/http_server_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/image_file_test.cpp b/test_package/image_file_test.cpp index eca9fa5e8..9a1ebfe67 100644 --- a/test_package/image_file_test.cpp +++ b/test_package/image_file_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_helper.hpp b/test_package/json_helper.hpp index e23afcb76..5ec636147 100644 --- a/test_package/json_helper.hpp +++ b/test_package/json_helper.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_mapping_test.cpp b/test_package/json_mapping_test.cpp index 6a33d2d02..25267594d 100644 --- a/test_package/json_mapping_test.cpp +++ b/test_package/json_mapping_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_parser_test.cpp b/test_package/json_parser_test.cpp index 3995e78a4..5db25737f 100644 --- a/test_package/json_parser_test.cpp +++ b/test_package/json_parser_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_printer_asset_test.cpp b/test_package/json_printer_asset_test.cpp index 7f478b080..d2e61b8f6 100644 --- a/test_package/json_printer_asset_test.cpp +++ b/test_package/json_printer_asset_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_printer_error_test.cpp b/test_package/json_printer_error_test.cpp index 147ce7967..f4a2a7291 100644 --- a/test_package/json_printer_error_test.cpp +++ b/test_package/json_printer_error_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_printer_probe_test.cpp b/test_package/json_printer_probe_test.cpp index 36b6e711e..b5544bc54 100644 --- a/test_package/json_printer_probe_test.cpp +++ b/test_package/json_printer_probe_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_printer_stream_test.cpp b/test_package/json_printer_stream_test.cpp index b00ed3b77..03b1fd8e2 100644 --- a/test_package/json_printer_stream_test.cpp +++ b/test_package/json_printer_stream_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_printer_test.cpp b/test_package/json_printer_test.cpp index 686ce425d..1fbb276f1 100644 --- a/test_package/json_printer_test.cpp +++ b/test_package/json_printer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/kinematics_test.cpp b/test_package/kinematics_test.cpp index 1dd927cb1..a2bf20d36 100644 --- a/test_package/kinematics_test.cpp +++ b/test_package/kinematics_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/mqtt_adapter_test.cpp b/test_package/mqtt_adapter_test.cpp index 9a14699be..2e2c4683f 100644 --- a/test_package/mqtt_adapter_test.cpp +++ b/test_package/mqtt_adapter_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/mqtt_isolated_test.cpp b/test_package/mqtt_isolated_test.cpp index 5b7ae824e..9789436c5 100644 --- a/test_package/mqtt_isolated_test.cpp +++ b/test_package/mqtt_isolated_test.cpp @@ -1,5 +1,5 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/mqtt_sink_2_test.cpp b/test_package/mqtt_sink_2_test.cpp index 111748a74..bdae53427 100644 --- a/test_package/mqtt_sink_2_test.cpp +++ b/test_package/mqtt_sink_2_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/mqtt_sink_test.cpp b/test_package/mqtt_sink_test.cpp index 85817679b..6675811f3 100644 --- a/test_package/mqtt_sink_test.cpp +++ b/test_package/mqtt_sink_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/mtconnect_xml_transform_test.cpp b/test_package/mtconnect_xml_transform_test.cpp index cb2b345ee..be3e5e6dc 100644 --- a/test_package/mtconnect_xml_transform_test.cpp +++ b/test_package/mtconnect_xml_transform_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/observation_test.cpp b/test_package/observation_test.cpp index feb6a10d4..3040dfe31 100644 --- a/test_package/observation_test.cpp +++ b/test_package/observation_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/period_filter_test.cpp b/test_package/period_filter_test.cpp index 839792cec..d38cd4d11 100644 --- a/test_package/period_filter_test.cpp +++ b/test_package/period_filter_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/pipeline_deliver_test.cpp b/test_package/pipeline_deliver_test.cpp index 4d611663f..3e632ee37 100644 --- a/test_package/pipeline_deliver_test.cpp +++ b/test_package/pipeline_deliver_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/pipeline_edit_test.cpp b/test_package/pipeline_edit_test.cpp index 130c09769..c5b68d90f 100644 --- a/test_package/pipeline_edit_test.cpp +++ b/test_package/pipeline_edit_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/qif_document_test.cpp b/test_package/qif_document_test.cpp index 269353f91..68097689f 100644 --- a/test_package/qif_document_test.cpp +++ b/test_package/qif_document_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/qname_test.cpp b/test_package/qname_test.cpp index 9462d1e0e..05ac55b35 100644 --- a/test_package/qname_test.cpp +++ b/test_package/qname_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/raw_material_test.cpp b/test_package/raw_material_test.cpp index 558dd262c..e7edecf6d 100644 --- a/test_package/raw_material_test.cpp +++ b/test_package/raw_material_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/references_test.cpp b/test_package/references_test.cpp index e81aba959..7d18c1148 100644 --- a/test_package/references_test.cpp +++ b/test_package/references_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/relationship_test.cpp b/test_package/relationship_test.cpp index c4feb60a6..b9ebf7f07 100644 --- a/test_package/relationship_test.cpp +++ b/test_package/relationship_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/response_document_test.cpp b/test_package/response_document_test.cpp index 0ae7316bc..50a513ba9 100644 --- a/test_package/response_document_test.cpp +++ b/test_package/response_document_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/routing_test.cpp b/test_package/routing_test.cpp index b26a86576..d4457f580 100644 --- a/test_package/routing_test.cpp +++ b/test_package/routing_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/sensor_configuration_test.cpp b/test_package/sensor_configuration_test.cpp index 1d94d46ab..eaf783b65 100644 --- a/test_package/sensor_configuration_test.cpp +++ b/test_package/sensor_configuration_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/shdr_tokenizer_test.cpp b/test_package/shdr_tokenizer_test.cpp index 8150df87a..76b754d43 100644 --- a/test_package/shdr_tokenizer_test.cpp +++ b/test_package/shdr_tokenizer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/solid_model_test.cpp b/test_package/solid_model_test.cpp index 169eea1ef..7cd6696a7 100644 --- a/test_package/solid_model_test.cpp +++ b/test_package/solid_model_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/specification_test.cpp b/test_package/specification_test.cpp index dff297813..3e3529fd6 100644 --- a/test_package/specification_test.cpp +++ b/test_package/specification_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/table_test.cpp b/test_package/table_test.cpp index 8da67faa2..215c8735c 100644 --- a/test_package/table_test.cpp +++ b/test_package/table_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/test_utilities.hpp b/test_package/test_utilities.hpp index 7fe6fea09..df1b0699e 100644 --- a/test_package/test_utilities.hpp +++ b/test_package/test_utilities.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/testadapter_service.cpp b/test_package/testadapter_service.cpp index 79f08bf74..23ae60b83 100644 --- a/test_package/testadapter_service.cpp +++ b/test_package/testadapter_service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/testadapter_service.hpp b/test_package/testadapter_service.hpp index 29ec1c06e..347324036 100644 --- a/test_package/testadapter_service.hpp +++ b/test_package/testadapter_service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/testsink_service.cpp b/test_package/testsink_service.cpp index 144ede526..245c9f595 100644 --- a/test_package/testsink_service.cpp +++ b/test_package/testsink_service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/testsink_service.hpp b/test_package/testsink_service.hpp index affd7c3f6..87b6d551e 100644 --- a/test_package/testsink_service.hpp +++ b/test_package/testsink_service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/timestamp_extractor_test.cpp b/test_package/timestamp_extractor_test.cpp index 49f05525d..dd355f17a 100644 --- a/test_package/timestamp_extractor_test.cpp +++ b/test_package/timestamp_extractor_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/tls_http_server_test.cpp b/test_package/tls_http_server_test.cpp index e141502a6..830d85f06 100644 --- a/test_package/tls_http_server_test.cpp +++ b/test_package/tls_http_server_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/topic_mapping_test.cpp b/test_package/topic_mapping_test.cpp index 71a53f0bc..5d92b44b0 100644 --- a/test_package/topic_mapping_test.cpp +++ b/test_package/topic_mapping_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/unit_conversion_test.cpp b/test_package/unit_conversion_test.cpp index e52ee6e9e..2998ae54f 100644 --- a/test_package/unit_conversion_test.cpp +++ b/test_package/unit_conversion_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/url_parser_test.cpp b/test_package/url_parser_test.cpp index 51afc286f..e2b31c5b4 100644 --- a/test_package/url_parser_test.cpp +++ b/test_package/url_parser_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/xml_parser_test.cpp b/test_package/xml_parser_test.cpp index 85814ea55..f2c532b94 100644 --- a/test_package/xml_parser_test.cpp +++ b/test_package/xml_parser_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/xml_printer_test.cpp b/test_package/xml_printer_test.cpp index 354bfd238..feba4c780 100644 --- a/test_package/xml_printer_test.cpp +++ b/test_package/xml_printer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); From 071baa5b35fe51eb49c064f18c9ae5a434802171 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 5 Apr 2024 23:28:20 -0400 Subject: [PATCH 003/128] first version of validation transform with pipeline --- CMakeLists.txt | 6 +- agent_lib/CMakeLists.txt | 5 +- src/mtconnect/pipeline/period_filter.hpp | 2 +- src/mtconnect/pipeline/validator.hpp | 99 ++++++++++++ src/mtconnect/printer/xml_printer.cpp | 2 +- .../source/adapter/adapter_pipeline.cpp | 5 + src/mtconnect/source/loopback_source.cpp | 7 + .../validation/observation_validations.hpp | 104 ++++++++++++- src/mtconnect/validation/observations.hpp | 2 +- test_package/CMakeLists.txt | 1 + test_package/observation_validation_test.cpp | 143 ++++++++++++++++++ 11 files changed, 366 insertions(+), 10 deletions(-) create mode 100644 src/mtconnect/pipeline/validator.hpp create mode 100644 test_package/observation_validation_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f47aa6a86..81d1e1c71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ # The version number. set(AGENT_VERSION_MAJOR 2) -set(AGENT_VERSION_MINOR 3) +set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) -set(AGENT_VERSION_BUILD 5) -set(AGENT_VERSION_RC "") +set(AGENT_VERSION_BUILD 0) +set(AGENT_VERSION_RC "RC1") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index 975b9fbb5..fbbbd70ce 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -183,6 +183,7 @@ set(AGENT_SOURCES "${SOURCE_DIR}/pipeline/topic_mapper.hpp" "${SOURCE_DIR}/pipeline/transform.hpp" "${SOURCE_DIR}/pipeline/upcase_value.hpp" + "${SOURCE_DIR}/pipeline/validator.hpp" # src/pipeline SOURCE_FILES_ONLY @@ -246,12 +247,12 @@ set(AGENT_SOURCES # src/sink/mqtt_sink HEADER_FILE_ONLY "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.hpp" - "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.hpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.hpp" #src/sink/mqtt_sink SOURCE_FILES_ONLY "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" - "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.cpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.cpp" # src/sink/rest_sink HEADER_FILE_ONLY diff --git a/src/mtconnect/pipeline/period_filter.hpp b/src/mtconnect/pipeline/period_filter.hpp index 6baf6545e..9073e8552 100644 --- a/src/mtconnect/pipeline/period_filter.hpp +++ b/src/mtconnect/pipeline/period_filter.hpp @@ -127,7 +127,7 @@ namespace mtconnect::pipeline { } } - return next(obs); + return next(std::move(obs)); } protected: diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp new file mode 100644 index 000000000..995200c94 --- /dev/null +++ b/src/mtconnect/pipeline/validator.hpp @@ -0,0 +1,99 @@ +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include +#include + +#include "mtconnect/config.hpp" +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/observation/observation.hpp" +#include "mtconnect/validation/observations.hpp" +#include "transform.hpp" + +namespace mtconnect::pipeline { + using namespace entity; + + /// @brief Map a token list to data items or asset types + class AGENT_LIB_API Validator : public Transform + { + public: + Validator(const Validator &) = default; + Validator(PipelineContextPtr context) + : Transform("Validator"), + m_contract(context->m_contract.get()) + { + m_guard = TypeGuard(RUN) || TypeGuard(SKIP); + } + + EntityPtr operator()(entity::EntityPtr &&entity) override + { + using namespace observation; + using namespace mtconnect::validation::observations; + auto evt = std::dynamic_pointer_cast(entity); + + auto di = evt->getDataItem(); + auto &type = di->getType(); + auto &value = evt->getValue(); + + if (value == "UNAVAILABLE") + { + evt->setProperty("quality", std::string("VALID")); + } + else + { + // Optimize + auto vocab = ControlledVocabularies.find(type); + if (vocab != ControlledVocabularies.end()) + { + auto &lits = vocab->second; + if (lits.size() != 0) + { + auto lit = lits.find(value); + if (lit != lits.end()) + { + evt->setProperty("quality", std::string("VALID")); + // Check for deprecated + } + else + { + evt->setProperty("quality", std::string("INVALID")); + // Log once + LOG(warning) << "Invalid value for '" << type << "' " << evt->getValue(); + } + } + else + { + evt->setProperty("quality", std::string("VALID")); + } + } + else + { + evt->setProperty("quality", std::string("UNVERIFIABLE")); + } + } + + return next(std::move(evt)); + } + + protected: + // Logging Context + std::set m_logOnce; + PipelineContract *m_contract; + std::unordered_map m_dataItemMap; + }; +} // namespace mtconnect::pipeline diff --git a/src/mtconnect/printer/xml_printer.cpp b/src/mtconnect/printer/xml_printer.cpp index 5e0aa1b2e..6448959e7 100644 --- a/src/mtconnect/printer/xml_printer.cpp +++ b/src/mtconnect/printer/xml_printer.cpp @@ -638,7 +638,7 @@ namespace mtconnect::printer { addAttribute(writer, "instanceId", to_string(instanceId)); if (m_validation) - addAttribute(writer, "instanceId", "true"s); + addAttribute(writer, "validation", "true"s); char version[32] = {0}; sprintf(version, "%d.%d.%d.%d", AGENT_VERSION_MAJOR, AGENT_VERSION_MINOR, AGENT_VERSION_PATCH, diff --git a/src/mtconnect/source/adapter/adapter_pipeline.cpp b/src/mtconnect/source/adapter/adapter_pipeline.cpp index 16a3dd505..615b47412 100644 --- a/src/mtconnect/source/adapter/adapter_pipeline.cpp +++ b/src/mtconnect/source/adapter/adapter_pipeline.cpp @@ -28,6 +28,7 @@ #include "mtconnect/pipeline/timestamp_extractor.hpp" #include "mtconnect/pipeline/topic_mapper.hpp" #include "mtconnect/pipeline/upcase_value.hpp" +#include "mtconnect/pipeline/validator.hpp" #include "mtconnect/source/adapter/adapter.hpp" using namespace std; @@ -138,6 +139,10 @@ namespace mtconnect { // Convert values if (IsOptionSet(m_options, configuration::ConversionRequired)) next = next->bind(make_shared()); + + // Validate Values + if (IsOptionSet(m_options, configuration::Validation)) + next = next->bind(make_shared(m_context)); // Filter dups, by delta, and by period next = next->bind(make_shared(m_context)); diff --git a/src/mtconnect/source/loopback_source.cpp b/src/mtconnect/source/loopback_source.cpp index 6cfbcdc6a..c28609b48 100644 --- a/src/mtconnect/source/loopback_source.cpp +++ b/src/mtconnect/source/loopback_source.cpp @@ -27,6 +27,7 @@ #include "mtconnect/pipeline/period_filter.hpp" #include "mtconnect/pipeline/timestamp_extractor.hpp" #include "mtconnect/pipeline/upcase_value.hpp" +#include "mtconnect/pipeline/validator.hpp" using namespace std; @@ -36,6 +37,8 @@ namespace mtconnect::source { using namespace pipeline; void LoopbackPipeline::build(const ConfigOptions &options) { + m_options = options; + clear(); TransformPtr next = m_start; @@ -54,6 +57,10 @@ namespace mtconnect::source { if (IsOptionSet(m_options, configuration::ConversionRequired)) next = next->bind(make_shared()); + // Validate Values + if (IsOptionSet(m_options, configuration::Validation)) + next = next->bind(make_shared(m_context)); + // Deliver next->bind(make_shared(m_context)); applySplices(); diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index 24af87c85..d0bb08abb 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,13 +1,25 @@ - Validation ControlledVocabularies { +const Validation ControlledVocabularies { + {"ACTIVE_AXES", {}}, {"ACTUATOR_STATE", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ALARM", {}}, + {"ASSET_CHANGED", {}}, + {"ASSET_REMOVED", {}}, {"AVAILABILITY", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, {"AXIS_COUPLING", {{"TANDEM", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}, {"SLAVE", 0}}}, + {"AXIS_FEEDRATE_OVERRIDE", {}}, {"AXIS_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, {"AXIS_STATE", {{"HOME", 0}, {"TRAVEL", 0}, {"PARKED", 0}, {"STOPPED", 0}}}, + {"BLOCK", {}}, + {"BLOCK_COUNT", {}}, {"CHUCK_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, {"CHUCK_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, + {"CODE", {}}, + {"COMPOSITION_STATE", {}}, {"CONTROLLER_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"EDIT", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, {"CONTROLLER_MODE_OVERRIDE", {{"ON", 0}, {"OFF", 0}}}, + {"COUPLED_AXES", {}}, + {"DATE_CODE", {}}, + {"DEVICE_UUID", {}}, {"DIRECTION", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, {"DOOR_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, {"EMERGENCY_STOP", {{"ARMED", 0}, {"TRIGGERED", 0}}}, @@ -15,25 +27,113 @@ {"EQUIPMENT_MODE", {{"ON", 0}, {"OFF", 0}}}, {"EXECUTION", {{"READY", 0}, {"ACTIVE", 0}, {"INTERRUPTED", 0}, {"FEED_HOLD", 0}, {"STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"PROGRAM_STOPPED", 0}, {"PROGRAM_COMPLETED", 0}, {"WAIT", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, {"FUNCTIONAL_MODE", {{"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}, {"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}}}, + {"HARDNESS", {}}, + {"LINE", {}}, + {"LINE_LABEL", {}}, + {"LINE_NUMBER", {}}, + {"MATERIAL", {}}, + {"MATERIAL_LAYER", {}}, + {"MESSAGE", {}}, + {"OPERATOR_ID", {}}, + {"PALLET_ID", {}}, + {"PART_COUNT", {}}, {"PART_DETECT", {{"PRESENT", 0}, {"NOT_PRESENT", 0}}}, + {"PART_ID", {}}, + {"PART_NUMBER", {}}, + {"PATH_FEEDRATE_OVERRIDE", {}}, {"PATH_MODE", {{"INDEPENDENT", 0}, {"MASTER", 0}, {"SYNCHRONOUS", 0}, {"MIRROR", 0}}}, {"POWER_STATE", {{"ON", 0}, {"OFF", 0}}}, {"POWER_STATUS", {{"ON", SCHEMA_VERSION(1, 1)}, {"OFF", SCHEMA_VERSION(1, 1)}}}, + {"PROCESS_TIME", {}}, + {"PROGRAM", {}}, + {"PROGRAM_COMMENT", {}}, {"PROGRAM_EDIT", {{"ACTIVE", 0}, {"READY", 0}, {"NOT_READY", 0}}}, + {"PROGRAM_EDIT_NAME", {}}, + {"PROGRAM_HEADER", {}}, + {"PROGRAM_LOCATION", {}}, {"PROGRAM_LOCATION_TYPE", {{"LOCAL", 0}, {"EXTERNAL", 0}}}, + {"PROGRAM_NEST_LEVEL", {}}, {"ROTARY_MODE", {{"SPINDLE", 0}, {"INDEX", 0}, {"CONTOUR", 0}}}, + {"ROTARY_VELOCITY_OVERRIDE", {}}, + {"SERIAL_NUMBER", {}}, {"SPINDLE_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"TOOL_ASSET_ID", {}}, + {"TOOL_GROUP", {}}, + {"TOOL_ID", {}}, + {"TOOL_NUMBER", {}}, + {"TOOL_OFFSET", {}}, + {"USER", {}}, + {"VARIABLE", {}}, {"WAIT_STATE", {{"POWERING_UP", 0}, {"POWERING_DOWN", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}, {"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"SECONDARY_PROCESS", 0}, {"PAUSING", 0}, {"RESUMING", 0}}}, + {"WIRE", {}}, + {"WORKHOLDING_ID", {}}, + {"WORK_OFFSET", {}}, + {"OPERATING_SYSTEM", {}}, + {"FIRMWARE", {}}, + {"APPLICATION", {}}, + {"LIBRARY", {}}, + {"HARDWARE", {}}, + {"NETWORK", {}}, + {"ROTATION", {}}, + {"TRANSLATION", {}}, + {"PROCESS_KIND_ID", {}}, {"PART_STATUS", {{"PASS", 0}, {"FAIL", 0}}}, + {"ALARM_LIMIT", {}}, + {"PROCESS_AGGREGATE_ID", {}}, + {"PART_KIND_ID", {}}, + {"ADAPTER_URI", {}}, + {"DEVICE_REMOVED", {}}, + {"DEVICE_CHANGED", {}}, + {"SPECIFICATION_LIMIT", {}}, {"CONNECTION_STATUS", {{"CLOSED", 0}, {"LISTEN", 0}, {"ESTABLISHED", 0}}}, + {"ADAPTER_SOFTWARE_VERSION", {}}, + {"SENSOR_ATTACHMENT", {}}, + {"CONTROL_LIMIT", {}}, + {"DEVICE_ADDED", {}}, + {"MTCONNECT_VERSION", {}}, + {"PROCESS_OCCURRENCE_ID", {}}, + {"PART_GROUP_ID", {}}, + {"PART_UNIQUE_ID", {}}, + {"ACTIVATION_COUNT", {}}, + {"DEACTIVATION_COUNT", {}}, + {"TRANSFER_COUNT", {}}, + {"LOAD_COUNT", {}}, {"PART_PROCESSING_STATE", {{"NEEDS_PROCESSING", 0}, {"IN_PROCESS", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"WAITING_FOR_TRANSIT", 0}, {"IN_TRANSIT", 0}, {"TRANSIT_COMPLETE", 0}}}, {"PROCESS_STATE", {{"INITIALIZING", 0}, {"READY", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INTERRUPTED", 0}, {"ABORTED", 0}}}, {"VALVE_STATE", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, {"LOCK_STATE", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, + {"UNLOAD_COUNT", {}}, + {"CYCLE_COUNT", {}}, {"OPERATING_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, + {"ASSET_COUNT", {}}, + {"MAINTENANCE_LIST", {}}, + {"FIXTURE_ID", {}}, {"PART_COUNT_TYPE", {{"EACH", 0}, {"BATCH", 0}}}, + {"CLOCK_TIME", {}}, + {"NETWORK_PORT", {}}, + {"HOST_NAME", {}}, {"LEAK_DETECT", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, {"BATTERY_STATE", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGING", 0}, {"DISCHARGED", 0}}}, + {"FEATURE_PERSISTENT_ID", {}}, + {"SENSOR_STATE", {}}, + {"COMPONENT_DATA", {}}, + {"WORK_OFFSETS", {}}, + {"TOOL_OFFSETS", {}}, + {"FEATURE_MEASUREMENT", {}}, + {"ADAPTER_URI", {}}, + {"MEASUREMENT_TYPE", {}}, + {"MEASUREMENT_VALUE", {}}, + {"MEASUREMENT_UNITS", {}}, {"ADAPTER_URI", {{"PASS", 0}, {"FAIL", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"UNDEFINED", 0}}}, - {"UNCERTAINTY_TYPE", {{"COMBINED", 0}, {"MEAN", 0}}} + {"UNCERTAINTY_TYPE", {{"COMBINED", 0}, {"MEAN", 0}}}, + {"UNCERTAINTY", {}}, + {"ALARM_LIMIT", {}}, + {"CONTROL_LIMIT", {}}, + {"SPECIFICATION_LIMIT", {}}, + {"TOOL_CUTTING_ITEM", {}}, + {"LOCATION_ADDRESS", {}}, + {"ACTIVE_POWER_SOURCE", {}}, + {"LOCATION_NARRATIVE", {}}, + {"THICKNESS", {}}, + {"LOCATION_SPATIAL_GEOGRAPHIC", {}} }; diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index f540d6131..a9d8c0055 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -25,5 +25,5 @@ namespace mtconnect::validation::observations { using Validation = std::unordered_map>; - extern Validation ControlledVocabularies; + const extern Validation ControlledVocabularies; } diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index 927946eb0..08a4e1ffd 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -277,6 +277,7 @@ add_agent_test(pipeline_edit FALSE pipeline) add_agent_test(mtconnect_xml_transform FALSE pipeline) add_agent_test(response_document FALSE pipeline) add_agent_test(json_mapping FALSE pipeline) +add_agent_test(observation_validation TRUE pipeline) add_agent_test(agent TRUE core) add_agent_test(globals FALSE core) diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp new file mode 100644 index 000000000..be6699ab0 --- /dev/null +++ b/test_package/observation_validation_test.cpp @@ -0,0 +1,143 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Ensure that gtest is the first header otherwise Windows raises an error +#include +// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) + +#include + +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/observation/observation.hpp" +#include "mtconnect/pipeline/validator.hpp" +#include "mtconnect/asset/asset.hpp" +#include "mtconnect/device_model/data_item/data_item.hpp" + +using namespace mtconnect; +using namespace mtconnect::pipeline; +using namespace mtconnect::observation; +using namespace mtconnect::asset; +using namespace mtconnect::device_model::data_item; +using namespace std; +using namespace date::literals; +using namespace std::literals; + +// main +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +class MockPipelineContract : public PipelineContract +{ +public: + MockPipelineContract(std::map &items, int32_t schemaVersion) + : m_dataItems(items), m_schemaVersion(schemaVersion) + {} + DevicePtr findDevice(const std::string &) override { return nullptr; } + DataItemPtr findDataItem(const std::string &device, const std::string &name) override + { + return m_dataItems[name]; + } + void eachDataItem(EachDataItem fun) override {} + void deliverObservation(observation::ObservationPtr obs) override {} + void deliverAsset(AssetPtr) override {} + void deliverDevices(std::list) override {} + int32_t getSchemaVersion() const override { return m_schemaVersion; } + void deliverAssetCommand(entity::EntityPtr) override {} + void deliverCommand(entity::EntityPtr) override {} + void deliverConnectStatus(entity::EntityPtr, const StringList &, bool) override {} + void sourceFailed(const std::string &id) override {} + const ObservationPtr checkDuplicate(const ObservationPtr &obs) const override { return obs; } + + std::map &m_dataItems; + int32_t m_schemaVersion; +}; + +class ObservationValidationTest : public testing::Test +{ +protected: + void SetUp() override + { + m_context = make_shared(); + m_validator = make_shared(m_context); + m_validator->bind(make_shared(TypeGuard(RUN))); + m_time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; + + ErrorList errors; + m_dataItem = DataItem::make( + {{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, + errors); + } + + void TearDown() override + { + m_validator.reset(); + m_dataItem.reset(); + m_context.reset(); + } + + shared_ptr m_validator; + shared_ptr m_context; + DataItemPtr m_dataItem; + Timestamp m_time; +}; + +TEST_F(ObservationValidationTest, should_validate_value) +{ + ErrorList errors; + auto event = Observation::make(m_dataItem, {{"VALUE", "READY"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); +} + +TEST_F(ObservationValidationTest, unavailable_should_be_valid) +{ + ErrorList errors; + auto event = Observation::make(m_dataItem, {{"VALUE", "UNAVAILABLE"s}}, m_time, errors); + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); +} + +TEST_F(ObservationValidationTest, should_detect_invalid_value) +{ + ErrorList errors; + auto event = Observation::make(m_dataItem, {{"VALUE", "FLABOR"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("INVALID", quality); +} + +TEST_F(ObservationValidationTest, should_not_validate_unknown_type) +{ + ErrorList errors; + m_dataItem = DataItem::make( + {{"id", "exec"s}, {"category", "EVENT"s}, {"type", "x:FLABOR"s}}, + errors); + + auto event = Observation::make(m_dataItem, {{"VALUE", "FLABOR"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("UNVERIFIABLE", quality); +} + From 367a6949b92703782adb4df539a7cd6eb9746d1b Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 5 Apr 2024 23:40:31 -0400 Subject: [PATCH 004/128] added log once logic --- src/mtconnect/pipeline/validator.hpp | 12 +++++++++++- src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index 995200c94..3524d03de 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -73,7 +73,17 @@ namespace mtconnect::pipeline { { evt->setProperty("quality", std::string("INVALID")); // Log once - LOG(warning) << "Invalid value for '" << type << "' " << evt->getValue(); + auto &id = di->getId(); + if (m_logOnce.count(id) < 1) + { + LOG(warning) << id << ": Invalid value for '" << type << "' " << evt->getValue(); + m_logOnce.insert(id); + } + else + { + LOG(trace) << id << ": Invalid value for '" << type << "' " << evt->getValue(); + + } } } else diff --git a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp index e673a97ea..7765ef2fb 100644 --- a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp +++ b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp @@ -123,7 +123,7 @@ namespace mtconnect { !IsOptionSet(m_options, configuration::MqttWs)) { m_client = make_shared(m_ioContext, m_options, - move(clientHandler)); + std::move(clientHandler)); } else if (IsOptionSet(m_options, configuration::MqttWs) && IsOptionSet(m_options, configuration::MqttTls)) From 11a6e6bad8558b044b2981501713b114c0e5d6c3 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 13:54:11 -0400 Subject: [PATCH 005/128] Added validation header tests --- src/mtconnect/pipeline/validator.hpp | 9 +- .../validation/observation_validations.hpp | 276 +++++++++--------- src/mtconnect/validation/observations.hpp | 2 +- test_package/agent_test.cpp | 73 ++++- 4 files changed, 211 insertions(+), 149 deletions(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index 3524d03de..ef2d74366 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -47,17 +47,16 @@ namespace mtconnect::pipeline { auto evt = std::dynamic_pointer_cast(entity); auto di = evt->getDataItem(); - auto &type = di->getType(); auto &value = evt->getValue(); - if (value == "UNAVAILABLE") + if (evt->isUnavailable()) { evt->setProperty("quality", std::string("VALID")); } else { // Optimize - auto vocab = ControlledVocabularies.find(type); + auto vocab = ControlledVocabularies.find(evt->getName()); if (vocab != ControlledVocabularies.end()) { auto &lits = vocab->second; @@ -76,12 +75,12 @@ namespace mtconnect::pipeline { auto &id = di->getId(); if (m_logOnce.count(id) < 1) { - LOG(warning) << id << ": Invalid value for '" << type << "' " << evt->getValue(); + LOG(warning) << "DataItem '" << id << "': Invalid value for '" << evt->getName() << "': '" << evt->getValue() << '\''; m_logOnce.insert(id); } else { - LOG(trace) << id << ": Invalid value for '" << type << "' " << evt->getValue(); + LOG(trace) << "DataItem '" << id << "': Invalid value for '" << evt->getName() << "': '" << evt->getValue() << '\''; } } diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index d0bb08abb..b4bb92f18 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,139 +1,139 @@ -const Validation ControlledVocabularies { - {"ACTIVE_AXES", {}}, - {"ACTUATOR_STATE", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"ALARM", {}}, - {"ASSET_CHANGED", {}}, - {"ASSET_REMOVED", {}}, - {"AVAILABILITY", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, - {"AXIS_COUPLING", {{"TANDEM", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}, {"SLAVE", 0}}}, - {"AXIS_FEEDRATE_OVERRIDE", {}}, - {"AXIS_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"AXIS_STATE", {{"HOME", 0}, {"TRAVEL", 0}, {"PARKED", 0}, {"STOPPED", 0}}}, - {"BLOCK", {}}, - {"BLOCK_COUNT", {}}, - {"CHUCK_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"CHUCK_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, - {"CODE", {}}, - {"COMPOSITION_STATE", {}}, - {"CONTROLLER_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"EDIT", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, - {"CONTROLLER_MODE_OVERRIDE", {{"ON", 0}, {"OFF", 0}}}, - {"COUPLED_AXES", {}}, - {"DATE_CODE", {}}, - {"DEVICE_UUID", {}}, - {"DIRECTION", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, - {"DOOR_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, - {"EMERGENCY_STOP", {{"ARMED", 0}, {"TRIGGERED", 0}}}, - {"END_OF_BAR", {{"YES", 0}, {"NO", 0}}}, - {"EQUIPMENT_MODE", {{"ON", 0}, {"OFF", 0}}}, - {"EXECUTION", {{"READY", 0}, {"ACTIVE", 0}, {"INTERRUPTED", 0}, {"FEED_HOLD", 0}, {"STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"PROGRAM_STOPPED", 0}, {"PROGRAM_COMPLETED", 0}, {"WAIT", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, - {"FUNCTIONAL_MODE", {{"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}, {"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}}}, - {"HARDNESS", {}}, - {"LINE", {}}, - {"LINE_LABEL", {}}, - {"LINE_NUMBER", {}}, - {"MATERIAL", {}}, - {"MATERIAL_LAYER", {}}, - {"MESSAGE", {}}, - {"OPERATOR_ID", {}}, - {"PALLET_ID", {}}, - {"PART_COUNT", {}}, - {"PART_DETECT", {{"PRESENT", 0}, {"NOT_PRESENT", 0}}}, - {"PART_ID", {}}, - {"PART_NUMBER", {}}, - {"PATH_FEEDRATE_OVERRIDE", {}}, - {"PATH_MODE", {{"INDEPENDENT", 0}, {"MASTER", 0}, {"SYNCHRONOUS", 0}, {"MIRROR", 0}}}, - {"POWER_STATE", {{"ON", 0}, {"OFF", 0}}}, - {"POWER_STATUS", {{"ON", SCHEMA_VERSION(1, 1)}, {"OFF", SCHEMA_VERSION(1, 1)}}}, - {"PROCESS_TIME", {}}, - {"PROGRAM", {}}, - {"PROGRAM_COMMENT", {}}, - {"PROGRAM_EDIT", {{"ACTIVE", 0}, {"READY", 0}, {"NOT_READY", 0}}}, - {"PROGRAM_EDIT_NAME", {}}, - {"PROGRAM_HEADER", {}}, - {"PROGRAM_LOCATION", {}}, - {"PROGRAM_LOCATION_TYPE", {{"LOCAL", 0}, {"EXTERNAL", 0}}}, - {"PROGRAM_NEST_LEVEL", {}}, - {"ROTARY_MODE", {{"SPINDLE", 0}, {"INDEX", 0}, {"CONTOUR", 0}}}, - {"ROTARY_VELOCITY_OVERRIDE", {}}, - {"SERIAL_NUMBER", {}}, - {"SPINDLE_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"TOOL_ASSET_ID", {}}, - {"TOOL_GROUP", {}}, - {"TOOL_ID", {}}, - {"TOOL_NUMBER", {}}, - {"TOOL_OFFSET", {}}, - {"USER", {}}, - {"VARIABLE", {}}, - {"WAIT_STATE", {{"POWERING_UP", 0}, {"POWERING_DOWN", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}, {"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"SECONDARY_PROCESS", 0}, {"PAUSING", 0}, {"RESUMING", 0}}}, - {"WIRE", {}}, - {"WORKHOLDING_ID", {}}, - {"WORK_OFFSET", {}}, - {"OPERATING_SYSTEM", {}}, - {"FIRMWARE", {}}, - {"APPLICATION", {}}, - {"LIBRARY", {}}, - {"HARDWARE", {}}, - {"NETWORK", {}}, - {"ROTATION", {}}, - {"TRANSLATION", {}}, - {"PROCESS_KIND_ID", {}}, - {"PART_STATUS", {{"PASS", 0}, {"FAIL", 0}}}, - {"ALARM_LIMIT", {}}, - {"PROCESS_AGGREGATE_ID", {}}, - {"PART_KIND_ID", {}}, - {"ADAPTER_URI", {}}, - {"DEVICE_REMOVED", {}}, - {"DEVICE_CHANGED", {}}, - {"SPECIFICATION_LIMIT", {}}, - {"CONNECTION_STATUS", {{"CLOSED", 0}, {"LISTEN", 0}, {"ESTABLISHED", 0}}}, - {"ADAPTER_SOFTWARE_VERSION", {}}, - {"SENSOR_ATTACHMENT", {}}, - {"CONTROL_LIMIT", {}}, - {"DEVICE_ADDED", {}}, - {"MTCONNECT_VERSION", {}}, - {"PROCESS_OCCURRENCE_ID", {}}, - {"PART_GROUP_ID", {}}, - {"PART_UNIQUE_ID", {}}, - {"ACTIVATION_COUNT", {}}, - {"DEACTIVATION_COUNT", {}}, - {"TRANSFER_COUNT", {}}, - {"LOAD_COUNT", {}}, - {"PART_PROCESSING_STATE", {{"NEEDS_PROCESSING", 0}, {"IN_PROCESS", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"WAITING_FOR_TRANSIT", 0}, {"IN_TRANSIT", 0}, {"TRANSIT_COMPLETE", 0}}}, - {"PROCESS_STATE", {{"INITIALIZING", 0}, {"READY", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INTERRUPTED", 0}, {"ABORTED", 0}}}, - {"VALVE_STATE", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, - {"LOCK_STATE", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, - {"UNLOAD_COUNT", {}}, - {"CYCLE_COUNT", {}}, - {"OPERATING_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, - {"ASSET_COUNT", {}}, - {"MAINTENANCE_LIST", {}}, - {"FIXTURE_ID", {}}, - {"PART_COUNT_TYPE", {{"EACH", 0}, {"BATCH", 0}}}, - {"CLOCK_TIME", {}}, - {"NETWORK_PORT", {}}, - {"HOST_NAME", {}}, - {"LEAK_DETECT", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, - {"BATTERY_STATE", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGING", 0}, {"DISCHARGED", 0}}}, - {"FEATURE_PERSISTENT_ID", {}}, - {"SENSOR_STATE", {}}, - {"COMPONENT_DATA", {}}, - {"WORK_OFFSETS", {}}, - {"TOOL_OFFSETS", {}}, - {"FEATURE_MEASUREMENT", {}}, - {"ADAPTER_URI", {}}, - {"MEASUREMENT_TYPE", {}}, - {"MEASUREMENT_VALUE", {}}, - {"MEASUREMENT_UNITS", {}}, - {"ADAPTER_URI", {{"PASS", 0}, {"FAIL", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"UNDEFINED", 0}}}, - {"UNCERTAINTY_TYPE", {{"COMBINED", 0}, {"MEAN", 0}}}, - {"UNCERTAINTY", {}}, - {"ALARM_LIMIT", {}}, - {"CONTROL_LIMIT", {}}, - {"SPECIFICATION_LIMIT", {}}, - {"TOOL_CUTTING_ITEM", {}}, - {"LOCATION_ADDRESS", {}}, - {"ACTIVE_POWER_SOURCE", {}}, - {"LOCATION_NARRATIVE", {}}, - {"THICKNESS", {}}, - {"LOCATION_SPATIAL_GEOGRAPHIC", {}} + Validation ControlledVocabularies { + {"ActiveAxes", {}}, + {"ActuatorState", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"Alarm", {}}, + {"AssetChanged", {}}, + {"AssetRemoved", {}}, + {"Availability", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, + {"AxisCoupling", {{"TANDEM", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}, {"SLAVE", 0}}}, + {"AxisFeedrateOverride", {}}, + {"AxisInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"AxisState", {{"HOME", 0}, {"TRAVEL", 0}, {"PARKED", 0}, {"STOPPED", 0}}}, + {"Block", {}}, + {"BlockCount", {}}, + {"ChuckInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ChuckState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, + {"Code", {}}, + {"CompositionState", {}}, + {"ControllerMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"EDIT", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, + {"ControllerModeOverride", {{"ON", 0}, {"OFF", 0}}}, + {"CoupledAxes", {}}, + {"DateCode", {}}, + {"DeviceUuid", {}}, + {"Direction", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, + {"DoorState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, + {"EmergencyStop", {{"ARMED", 0}, {"TRIGGERED", 0}}}, + {"EndOfBar", {{"YES", 0}, {"NO", 0}}}, + {"EquipmentMode", {{"ON", 0}, {"OFF", 0}}}, + {"Execution", {{"READY", 0}, {"ACTIVE", 0}, {"INTERRUPTED", 0}, {"FEED_HOLD", 0}, {"STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"PROGRAM_STOPPED", 0}, {"PROGRAM_COMPLETED", 0}, {"WAIT", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, + {"FunctionalMode", {{"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}, {"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}}}, + {"Hardness", {}}, + {"Line", {}}, + {"LineLabel", {}}, + {"LineNumber", {}}, + {"Material", {}}, + {"MaterialLayer", {}}, + {"Message", {}}, + {"OperatorId", {}}, + {"PalletId", {}}, + {"PartCount", {}}, + {"PartDetect", {{"PRESENT", 0}, {"NOT_PRESENT", 0}}}, + {"PartId", {}}, + {"PartNumber", {}}, + {"PathFeedrateOverride", {}}, + {"PathMode", {{"INDEPENDENT", 0}, {"MASTER", 0}, {"SYNCHRONOUS", 0}, {"MIRROR", 0}}}, + {"PowerState", {{"ON", 0}, {"OFF", 0}}}, + {"PowerStatus", {{"ON", SCHEMA_VERSION(1, 1)}, {"OFF", SCHEMA_VERSION(1, 1)}}}, + {"ProcessTime", {}}, + {"Program", {}}, + {"ProgramComment", {}}, + {"ProgramEdit", {{"ACTIVE", 0}, {"READY", 0}, {"NOT_READY", 0}}}, + {"ProgramEditName", {}}, + {"ProgramHeader", {}}, + {"ProgramLocation", {}}, + {"ProgramLocationType", {{"LOCAL", 0}, {"EXTERNAL", 0}}}, + {"ProgramNestLevel", {}}, + {"RotaryMode", {{"SPINDLE", 0}, {"INDEX", 0}, {"CONTOUR", 0}}}, + {"RotaryVelocityOverride", {}}, + {"SerialNumber", {}}, + {"SpindleInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ToolAssetId", {}}, + {"ToolGroup", {}}, + {"ToolId", {}}, + {"ToolNumber", {}}, + {"ToolOffset", {}}, + {"User", {}}, + {"Variable", {}}, + {"WaitState", {{"POWERING_UP", 0}, {"POWERING_DOWN", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}, {"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"SECONDARY_PROCESS", 0}, {"PAUSING", 0}, {"RESUMING", 0}}}, + {"Wire", {}}, + {"WorkholdingId", {}}, + {"WorkOffset", {}}, + {"OperatingSystem", {}}, + {"Firmware", {}}, + {"Application", {}}, + {"Library", {}}, + {"Hardware", {}}, + {"Network", {}}, + {"Rotation", {}}, + {"Translation", {}}, + {"ProcessKindId", {}}, + {"PartStatus", {{"PASS", 0}, {"FAIL", 0}}}, + {"AlarmLimit", {}}, + {"ProcessAggregateId", {}}, + {"PartKindId", {}}, + {"AdapterURI", {}}, + {"DeviceRemoved", {}}, + {"DeviceChanged", {}}, + {"SpecificationLimit", {}}, + {"ConnectionStatus", {{"CLOSED", 0}, {"LISTEN", 0}, {"ESTABLISHED", 0}}}, + {"AdapterSoftwareVersion", {}}, + {"SensorAttachment", {}}, + {"ControlLimit", {}}, + {"DeviceAdded", {}}, + {"MTConnectVersion", {}}, + {"ProcessOccurrenceId", {}}, + {"PartGroupId", {}}, + {"PartUniqueId", {}}, + {"ActivationCount", {}}, + {"DeactivationCount", {}}, + {"TransferCount", {}}, + {"LoadCount", {}}, + {"PartProcessingState", {{"NEEDS_PROCESSING", 0}, {"IN_PROCESS", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"WAITING_FOR_TRANSIT", 0}, {"IN_TRANSIT", 0}, {"TRANSIT_COMPLETE", 0}}}, + {"ProcessState", {{"INITIALIZING", 0}, {"READY", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INTERRUPTED", 0}, {"ABORTED", 0}}}, + {"ValveState", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, + {"LockState", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, + {"UnloadCount", {}}, + {"CycleCount", {}}, + {"OperatingMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, + {"AssetCount", {}}, + {"MaintenanceList", {}}, + {"FixtureId", {}}, + {"PartCountType", {{"EACH", 0}, {"BATCH", 0}}}, + {"ClockTime", {}}, + {"NetworkPort", {}}, + {"HostName", {}}, + {"LeakDetect", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, + {"BatteryState", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGING", 0}, {"DISCHARGED", 0}}}, + {"FeaturePersisitentId", {}}, + {"SensorState", {}}, + {"ComponentData", {}}, + {"WorkOffsets", {}}, + {"ToolOffsets", {}}, + {"FeatureMeasurement", {}}, + {"CharacteristicPersistentId", {}}, + {"MeasurementType", {}}, + {"MeasurementValue", {}}, + {"MeasurementUnits", {}}, + {"CharacteristicStatus", {{"PASS", 0}, {"FAIL", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"UNDEFINED", 0}}}, + {"UncertaintyType", {{"COMBINED", 0}, {"MEAN", 0}}}, + {"Uncertainty", {}}, + {"AlarmLimits", {}}, + {"ControlLimits", {}}, + {"SpecificationLimits", {}}, + {"ToolCuttingItem", {}}, + {"LocationAddress", {}}, + {"ActivePowerSource", {}}, + {"LocationNarrative", {}}, + {"Thickness", {}}, + {"LocationSpatialGeographic", {}} }; diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index a9d8c0055..f540d6131 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -25,5 +25,5 @@ namespace mtconnect::validation::observations { using Validation = std::unordered_map>; - const extern Validation ControlledVocabularies; + extern Validation ControlledVocabularies; } diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index d7b673f84..899d2af8c 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -548,7 +548,7 @@ TEST_F(AgentTest, SampleAtNextSeq) } } -TEST_F(AgentTest, SampleCount) +TEST_F(AgentTest, should_give_correct_number_of_samples_with_count) { QueryMap query; addAdapter(); @@ -584,7 +584,7 @@ TEST_F(AgentTest, SampleCount) } } -TEST_F(AgentTest, SampleLastCount) +TEST_F(AgentTest, should_give_correct_number_of_samples_with_negative_count) { QueryMap query; addAdapter(); @@ -620,7 +620,7 @@ TEST_F(AgentTest, SampleLastCount) } } -TEST_F(AgentTest, SampleToParameter) +TEST_F(AgentTest, should_give_correct_number_of_samples_with_to_parameter) { QueryMap query; addAdapter(); @@ -683,7 +683,7 @@ TEST_F(AgentTest, SampleToParameter) // to > from } -TEST_F(AgentTest, EmptyStream) +TEST_F(AgentTest, should_give_empty_stream_with_no_new_samples) { { PARSE_XML_RESPONSE("/current"); @@ -741,7 +741,7 @@ TEST_F(AgentTest, AddToBuffer) } } -TEST_F(AgentTest, SequenceNumberRollover) +TEST_F(AgentTest, should_int_64_sequences_should_not_truncate_at_32_bits) { #ifndef WIN32 QueryMap query; @@ -3075,3 +3075,66 @@ TEST_F(AgentTest, should_set_sender_from_config_in_XML_header) ASSERT_XML_PATH_EQUAL(doc, "//m:Header@sender", "MachineXXX"); } } + +TEST_F(AgentTest, should_set_validation_flag_in_header_when_version_2_5_validation_on) +{ + auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.5", 4, false, + true, {{configuration::Validation, true}}); + ASSERT_TRUE(agent); + { + PARSE_XML_RESPONSE("/probe"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); + } + + { + PARSE_XML_RESPONSE("/current"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); + } + + { + PARSE_XML_RESPONSE("/sample"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); + } +} + +TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_version_below_2_5) +{ + auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.4", 4, false, + true, {{configuration::Validation, true}}); + ASSERT_TRUE(agent); + { + PARSE_XML_RESPONSE("/probe"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } + + { + PARSE_XML_RESPONSE("/current"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } + + { + PARSE_XML_RESPONSE("/sample"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } +} + +TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_false) +{ + auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.5", 4, false, + true, {{configuration::Validation, false}}); + ASSERT_TRUE(agent); + { + PARSE_XML_RESPONSE("/probe"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } + + { + PARSE_XML_RESPONSE("/current"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } + + { + PARSE_XML_RESPONSE("/sample"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } +} From e99d86d78120ee62a12e1ade223d10328835b5bb Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 13:54:11 -0400 Subject: [PATCH 006/128] Added validation header tests --- src/mtconnect/agent.cpp | 9 +- src/mtconnect/pipeline/validator.hpp | 19 ++--- src/mtconnect/printer/json_printer.cpp | 22 ++--- src/mtconnect/printer/printer.hpp | 13 +-- src/mtconnect/printer/xml_printer.cpp | 7 +- .../source/adapter/adapter_pipeline.cpp | 2 +- src/mtconnect/source/loopback_source.cpp | 2 +- .../validation/observation_validations.hpp | 83 ++++++++++++++++--- src/mtconnect/validation/observations.hpp | 9 +- test_package/agent_test.cpp | 12 +++ test_package/observation_validation_test.cpp | 27 +++--- 11 files changed, 136 insertions(+), 69 deletions(-) diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index a2eaa939c..b298501ee 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -56,9 +56,8 @@ #include "mtconnect/sink/rest_sink/file_cache.hpp" #include "mtconnect/sink/rest_sink/session.hpp" #include "mtconnect/utilities.hpp" -#include "mtconnect/version.h" - #include "mtconnect/validation/observations.hpp" +#include "mtconnect/version.h" using namespace std; @@ -171,13 +170,14 @@ namespace mtconnect { if (!m_observationsInitialized) { - if (m_intSchemaVersion < SCHEMA_VERSION(2, 5) && IsOptionSet(m_options, mtconnect::configuration::Validation)) + if (m_intSchemaVersion < SCHEMA_VERSION(2, 5) && + IsOptionSet(m_options, mtconnect::configuration::Validation)) { m_validation = false; for (auto &printer : m_printers) printer.second->setValidation(false); } - + for (auto device : m_deviceIndex) initializeDataItems(device); @@ -201,7 +201,6 @@ namespace mtconnect { } m_observationsInitialized = true; - } } diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index ef2d74366..b99b72565 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -27,28 +27,26 @@ namespace mtconnect::pipeline { using namespace entity; - + /// @brief Map a token list to data items or asset types class AGENT_LIB_API Validator : public Transform { public: Validator(const Validator &) = default; Validator(PipelineContextPtr context) - : Transform("Validator"), - m_contract(context->m_contract.get()) + : Transform("Validator"), m_contract(context->m_contract.get()) { m_guard = TypeGuard(RUN) || TypeGuard(SKIP); } - + EntityPtr operator()(entity::EntityPtr &&entity) override { using namespace observation; using namespace mtconnect::validation::observations; auto evt = std::dynamic_pointer_cast(entity); - + auto di = evt->getDataItem(); auto &value = evt->getValue(); - if (evt->isUnavailable()) { evt->setProperty("quality", std::string("VALID")); @@ -75,13 +73,14 @@ namespace mtconnect::pipeline { auto &id = di->getId(); if (m_logOnce.count(id) < 1) { - LOG(warning) << "DataItem '" << id << "': Invalid value for '" << evt->getName() << "': '" << evt->getValue() << '\''; + LOG(warning) << "DataItem '" << id << "': Invalid value for '" << evt->getName() + << "': '" << evt->getValue() << '\''; m_logOnce.insert(id); } else { - LOG(trace) << "DataItem '" << id << "': Invalid value for '" << evt->getName() << "': '" << evt->getValue() << '\''; - + LOG(trace) << "DataItem '" << id << "': Invalid value for '" << evt->getName() + << "': '" << evt->getValue() << '\''; } } } @@ -95,7 +94,7 @@ namespace mtconnect::pipeline { evt->setProperty("quality", std::string("UNVERIFIABLE")); } } - + return next(std::move(evt)); } diff --git a/src/mtconnect/printer/json_printer.cpp b/src/mtconnect/printer/json_printer.cpp index 2720d5eaa..287203797 100644 --- a/src/mtconnect/printer/json_printer.cpp +++ b/src/mtconnect/printer/json_printer.cpp @@ -60,8 +60,7 @@ namespace mtconnect::printer { template inline void header(AutoJsonObject &obj, const string &version, const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, - const string &schemaVersion, const string modelChangeTime, - bool validation) + const string &schemaVersion, const string modelChangeTime, bool validation) { obj.AddPairs("version", version, "creationTime", getCurrentTime(GMT), "testIndicator", false, "instanceId", instanceId, "sender", hostname, "schemaVersion", schemaVersion); @@ -72,7 +71,6 @@ namespace mtconnect::printer { obj.AddPairs("bufferSize", bufferSize); if (validation) obj.AddPairs("validation", true); - } template @@ -80,10 +78,10 @@ namespace mtconnect::printer { const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetBufferSize, const unsigned int assetCount, const string &schemaVersion, - const string modelChangeTime, - const bool validation) + const string modelChangeTime, const bool validation) { - header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, validation); + header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, + validation); obj.AddPairs("assetBufferSize", assetBufferSize, "assetCount", assetCount); } @@ -92,10 +90,10 @@ namespace mtconnect::printer { const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSequence, const uint64_t firstSequence, const uint64_t lastSequence, const string &schemaVersion, - const string modelChangeTime, - const bool validation) + const string modelChangeTime, const bool validation) { - header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, validation); + header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, + validation); obj.AddPairs("nextSequence", nextSequence, "lastSequence", lastSequence, "firstSequence", firstSequence); } @@ -213,8 +211,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); probeAssetHeader(obj, m_version, m_senderName, instanceId, 0, bufferSize, assetCount, - *m_schemaVersion, m_modelChangeTime, - m_validation); + *m_schemaVersion, m_modelChangeTime, m_validation); } { obj.Key("Assets"); @@ -412,8 +409,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); streamHeader(obj, m_version, m_senderName, instanceId, bufferSize, nextSeq, firstSeq, - lastSeq, *m_schemaVersion, m_modelChangeTime, - m_validation); + lastSeq, *m_schemaVersion, m_modelChangeTime, m_validation); } { diff --git a/src/mtconnect/printer/printer.hpp b/src/mtconnect/printer/printer.hpp index 4e39cb0a8..52943c175 100644 --- a/src/mtconnect/printer/printer.hpp +++ b/src/mtconnect/printer/printer.hpp @@ -49,7 +49,9 @@ namespace mtconnect { public: /// @brief construct a printer /// @param pretty `true` if content should be pretty printed - Printer(bool pretty = false, bool validation = false) : m_pretty(pretty), m_validation(validation) {} + Printer(bool pretty = false, bool validation = false) + : m_pretty(pretty), m_validation(validation) + {} virtual ~Printer() = default; /// @brief Generate an MTConnect Error document @@ -145,19 +147,18 @@ namespace mtconnect { const_cast(this)->m_schemaVersion.emplace(ver); } } - + /// @brief Get validation header flag state /// @returns validation state bool getValidation() const { return m_validation; } - + /// @brief sets validation state /// @param validation the validation state void setValidation(bool v) { m_validation = v; } - protected: - bool m_pretty; //< Turns pretty printing on - bool m_validation; //< Sets validation flag in header + bool m_pretty; //< Turns pretty printing on + bool m_validation; //< Sets validation flag in header std::string m_modelChangeTime; std::optional m_schemaVersion; std::string m_senderName {"localhost"}; diff --git a/src/mtconnect/printer/xml_printer.cpp b/src/mtconnect/printer/xml_printer.cpp index 6448959e7..56e059470 100644 --- a/src/mtconnect/printer/xml_printer.cpp +++ b/src/mtconnect/printer/xml_printer.cpp @@ -100,7 +100,10 @@ namespace mtconnect::printer { xmlBufferPtr m_buf; }; - XmlPrinter::XmlPrinter(bool pretty, bool validation) : Printer(pretty, validation) { NAMED_SCOPE("xml.printer"); } + XmlPrinter::XmlPrinter(bool pretty, bool validation) : Printer(pretty, validation) + { + NAMED_SCOPE("xml.printer"); + } void XmlPrinter::addDevicesNamespace(const std::string &urn, const std::string &location, const std::string &prefix) @@ -636,7 +639,7 @@ namespace mtconnect::printer { addAttribute(writer, "sender", m_senderName); addAttribute(writer, "instanceId", to_string(instanceId)); - + if (m_validation) addAttribute(writer, "validation", "true"s); diff --git a/src/mtconnect/source/adapter/adapter_pipeline.cpp b/src/mtconnect/source/adapter/adapter_pipeline.cpp index 615b47412..6432a6cfc 100644 --- a/src/mtconnect/source/adapter/adapter_pipeline.cpp +++ b/src/mtconnect/source/adapter/adapter_pipeline.cpp @@ -139,7 +139,7 @@ namespace mtconnect { // Convert values if (IsOptionSet(m_options, configuration::ConversionRequired)) next = next->bind(make_shared()); - + // Validate Values if (IsOptionSet(m_options, configuration::Validation)) next = next->bind(make_shared(m_context)); diff --git a/src/mtconnect/source/loopback_source.cpp b/src/mtconnect/source/loopback_source.cpp index c28609b48..94248bc56 100644 --- a/src/mtconnect/source/loopback_source.cpp +++ b/src/mtconnect/source/loopback_source.cpp @@ -38,7 +38,7 @@ namespace mtconnect::source { void LoopbackPipeline::build(const ConfigOptions &options) { m_options = options; - + clear(); TransformPtr next = m_start; diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index b4bb92f18..1f7cb73ef 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,4 +1,4 @@ - Validation ControlledVocabularies { +Validation ControlledVocabularies { {"ActiveAxes", {}}, {"ActuatorState", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, {"Alarm", {}}, @@ -15,18 +15,43 @@ {"ChuckState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, {"Code", {}}, {"CompositionState", {}}, - {"ControllerMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"EDIT", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, + {"ControllerMode", + {{"AUTOMATIC", 0}, + {"MANUAL", 0}, + {"MANUAL_DATA_INPUT", 0}, + {"SEMI_AUTOMATIC", 0}, + {"EDIT", 0}, + {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, {"ControllerModeOverride", {{"ON", 0}, {"OFF", 0}}}, {"CoupledAxes", {}}, {"DateCode", {}}, {"DeviceUuid", {}}, - {"Direction", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, + {"Direction", + {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, + {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, + {"POSITIVE", SCHEMA_VERSION(1, 4)}, + {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, {"DoorState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, {"EmergencyStop", {{"ARMED", 0}, {"TRIGGERED", 0}}}, {"EndOfBar", {{"YES", 0}, {"NO", 0}}}, {"EquipmentMode", {{"ON", 0}, {"OFF", 0}}}, - {"Execution", {{"READY", 0}, {"ACTIVE", 0}, {"INTERRUPTED", 0}, {"FEED_HOLD", 0}, {"STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"PROGRAM_STOPPED", 0}, {"PROGRAM_COMPLETED", 0}, {"WAIT", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, - {"FunctionalMode", {{"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}, {"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}}}, + {"Execution", + {{"READY", 0}, + {"ACTIVE", 0}, + {"INTERRUPTED", 0}, + {"FEED_HOLD", 0}, + {"STOPPED", 0}, + {"OPTIONAL_STOP", 0}, + {"PROGRAM_STOPPED", 0}, + {"PROGRAM_COMPLETED", 0}, + {"WAIT", 0}, + {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, + {"FunctionalMode", + {{"PRODUCTION", 0}, + {"SETUP", 0}, + {"TEARDOWN", 0}, + {"MAINTENANCE", 0}, + {"PROCESS_DEVELOPMENT", 0}}}, {"Hardness", {}}, {"Line", {}}, {"LineLabel", {}}, @@ -64,7 +89,18 @@ {"ToolOffset", {}}, {"User", {}}, {"Variable", {}}, - {"WaitState", {{"POWERING_UP", 0}, {"POWERING_DOWN", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}, {"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"SECONDARY_PROCESS", 0}, {"PAUSING", 0}, {"RESUMING", 0}}}, + {"WaitState", + {{"POWERING_UP", 0}, + {"POWERING_DOWN", 0}, + {"PART_LOAD", 0}, + {"PART_UNLOAD", 0}, + {"TOOL_LOAD", 0}, + {"TOOL_UNLOAD", 0}, + {"MATERIAL_LOAD", 0}, + {"MATERIAL_UNLOAD", 0}, + {"SECONDARY_PROCESS", 0}, + {"PAUSING", 0}, + {"RESUMING", 0}}}, {"Wire", {}}, {"WorkholdingId", {}}, {"WorkOffset", {}}, @@ -98,8 +134,26 @@ {"DeactivationCount", {}}, {"TransferCount", {}}, {"LoadCount", {}}, - {"PartProcessingState", {{"NEEDS_PROCESSING", 0}, {"IN_PROCESS", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"WAITING_FOR_TRANSIT", 0}, {"IN_TRANSIT", 0}, {"TRANSIT_COMPLETE", 0}}}, - {"ProcessState", {{"INITIALIZING", 0}, {"READY", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INTERRUPTED", 0}, {"ABORTED", 0}}}, + {"PartProcessingState", + {{"NEEDS_PROCESSING", 0}, + {"IN_PROCESS", 0}, + {"PROCESSING_ENDED", 0}, + {"PROCESSING_ENDED_COMPLETE", 0}, + {"PROCESSING_ENDED_STOPPED", 0}, + {"PROCESSING_ENDED_ABORTED", 0}, + {"PROCESSING_ENDED_LOST", 0}, + {"PROCESSING_ENDED_SKIPPED", 0}, + {"PROCESSING_ENDED_REJECTED", 0}, + {"WAITING_FOR_TRANSIT", 0}, + {"IN_TRANSIT", 0}, + {"TRANSIT_COMPLETE", 0}}}, + {"ProcessState", + {{"INITIALIZING", 0}, + {"READY", 0}, + {"ACTIVE", 0}, + {"COMPLETE", 0}, + {"INTERRUPTED", 0}, + {"ABORTED", 0}}}, {"ValveState", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, {"LockState", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, {"UnloadCount", {}}, @@ -124,7 +178,15 @@ {"MeasurementType", {}}, {"MeasurementValue", {}}, {"MeasurementUnits", {}}, - {"CharacteristicStatus", {{"PASS", 0}, {"FAIL", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"UNDEFINED", 0}}}, + {"CharacteristicStatus", + {{"PASS", 0}, + {"FAIL", 0}, + {"REWORK", 0}, + {"SYSTEM_ERROR", 0}, + {"INDETERMINATE", 0}, + {"NOT_ANALYZED", 0}, + {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, + {"UNDEFINED", 0}}}, {"UncertaintyType", {{"COMBINED", 0}, {"MEAN", 0}}}, {"Uncertainty", {}}, {"AlarmLimits", {}}, @@ -135,5 +197,4 @@ {"ActivePowerSource", {}}, {"LocationNarrative", {}}, {"Thickness", {}}, - {"LocationSpatialGeographic", {}} - }; + {"LocationSpatialGeographic", {}}}; diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index f540d6131..808e0ea01 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -17,13 +17,12 @@ #pragma once -#include "../utilities.hpp" - -#include #include +#include + +#include "../utilities.hpp" namespace mtconnect::validation::observations { using Validation = std::unordered_map>; - extern Validation ControlledVocabularies; -} +} // namespace mtconnect::validation::observations diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 899d2af8c..800da2135 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -3090,7 +3090,11 @@ TEST_F(AgentTest, should_set_validation_flag_in_header_when_version_2_5_validati PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); } +<<<<<<< HEAD +======= + +>>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); @@ -3111,7 +3115,11 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_version_below_2_ PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); } +<<<<<<< HEAD +======= + +>>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); @@ -3132,7 +3140,11 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_fa PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); } +<<<<<<< HEAD +======= + +>>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index be6699ab0..6dbfbe21c 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -21,11 +21,11 @@ #include +#include "mtconnect/asset/asset.hpp" +#include "mtconnect/device_model/data_item/data_item.hpp" #include "mtconnect/entity/entity.hpp" #include "mtconnect/observation/observation.hpp" #include "mtconnect/pipeline/validator.hpp" -#include "mtconnect/asset/asset.hpp" -#include "mtconnect/device_model/data_item/data_item.hpp" using namespace mtconnect; using namespace mtconnect::pipeline; @@ -80,18 +80,17 @@ class ObservationValidationTest : public testing::Test m_time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; ErrorList errors; - m_dataItem = DataItem::make( - {{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, - errors); + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, errors); } - void TearDown() override + void TearDown() override { m_validator.reset(); m_dataItem.reset(); m_context.reset(); } - + shared_ptr m_validator; shared_ptr m_context; DataItemPtr m_dataItem; @@ -102,7 +101,7 @@ TEST_F(ObservationValidationTest, should_validate_value) { ErrorList errors; auto event = Observation::make(m_dataItem, {{"VALUE", "READY"s}}, m_time, errors); - + auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("VALID", quality); @@ -121,7 +120,7 @@ TEST_F(ObservationValidationTest, should_detect_invalid_value) { ErrorList errors; auto event = Observation::make(m_dataItem, {{"VALUE", "FLABOR"s}}, m_time, errors); - + auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("INVALID", quality); @@ -130,14 +129,12 @@ TEST_F(ObservationValidationTest, should_detect_invalid_value) TEST_F(ObservationValidationTest, should_not_validate_unknown_type) { ErrorList errors; - m_dataItem = DataItem::make( - {{"id", "exec"s}, {"category", "EVENT"s}, {"type", "x:FLABOR"s}}, - errors); - + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "x:FLABOR"s}}, errors); + auto event = Observation::make(m_dataItem, {{"VALUE", "FLABOR"s}}, m_time, errors); - + auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("UNVERIFIABLE", quality); } - From 556f87ae783cac0e44195915a566b572ff3d0e93 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 14:20:34 -0400 Subject: [PATCH 007/128] Added deprecated support for observations --- src/mtconnect/pipeline/validator.hpp | 7 +++- test_package/observation_validation_test.cpp | 42 +++++++++++++++++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index b99b72565..8a0660823 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -64,7 +64,12 @@ namespace mtconnect::pipeline { if (lit != lits.end()) { evt->setProperty("quality", std::string("VALID")); - // Check for deprecated + + // Check if deprecated + if (lit->second > 0 && m_contract->getSchemaVersion() > lit->second) + { + evt->setProperty("deprecated", true); + } } else { diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index 6dbfbe21c..6ba8dd6cc 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -46,13 +46,11 @@ int main(int argc, char *argv[]) class MockPipelineContract : public PipelineContract { public: - MockPipelineContract(std::map &items, int32_t schemaVersion) - : m_dataItems(items), m_schemaVersion(schemaVersion) - {} + MockPipelineContract(int32_t schemaVersion) : m_schemaVersion(schemaVersion) {} DevicePtr findDevice(const std::string &) override { return nullptr; } DataItemPtr findDataItem(const std::string &device, const std::string &name) override { - return m_dataItems[name]; + return nullptr; } void eachDataItem(EachDataItem fun) override {} void deliverObservation(observation::ObservationPtr obs) override {} @@ -65,7 +63,6 @@ class MockPipelineContract : public PipelineContract void sourceFailed(const std::string &id) override {} const ObservationPtr checkDuplicate(const ObservationPtr &obs) const override { return obs; } - std::map &m_dataItems; int32_t m_schemaVersion; }; @@ -75,6 +72,7 @@ class ObservationValidationTest : public testing::Test void SetUp() override { m_context = make_shared(); + m_context->m_contract = make_unique(SCHEMA_VERSION(2, 5)); m_validator = make_shared(m_context); m_validator->bind(make_shared(TypeGuard(RUN))); m_time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -138,3 +136,37 @@ TEST_F(ObservationValidationTest, should_not_validate_unknown_type) auto quality = evt->get("quality"); ASSERT_EQ("UNVERIFIABLE", quality); } + +TEST_F(ObservationValidationTest, should_set_deprecated_flag_when_deprecated) +{ + ErrorList errors; + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, errors); + + auto event = Observation::make(m_dataItem, {{"VALUE", "PROGRAM_OPTIONAL_STOP"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); + + auto dep = evt->get("deprecated"); + ASSERT_TRUE(dep); +} + +TEST_F(ObservationValidationTest, should_not_set_deprecated_flag_when_deprecated_version_greater) +{ + ErrorList errors; + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, errors); + + auto contract = static_cast(m_context->m_contract.get()); + contract->m_schemaVersion = SCHEMA_VERSION(1, 3); + + auto event = Observation::make(m_dataItem, {{"VALUE", "PROGRAM_OPTIONAL_STOP"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); + + ASSERT_FALSE(evt->hasProperty("deprecated")); +} From ca2d0398fe669270b6c0e9bdf3f8251527d7c734 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 14:30:56 -0400 Subject: [PATCH 008/128] removed version markers in agent test --- test_package/agent_test.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 800da2135..82bf2ba98 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -3090,11 +3090,7 @@ TEST_F(AgentTest, should_set_validation_flag_in_header_when_version_2_5_validati PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); } -<<<<<<< HEAD - -======= ->>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); @@ -3115,11 +3111,7 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_version_below_2_ PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); } -<<<<<<< HEAD - -======= ->>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); @@ -3140,11 +3132,7 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_fa PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); } -<<<<<<< HEAD - -======= ->>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); From 76b8be5f885157d931349dfc0b647fa9abbbbe13 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 14:39:51 -0400 Subject: [PATCH 009/128] Do not validate tables or data sets. --- src/mtconnect/pipeline/validator.hpp | 5 ++-- test_package/observation_validation_test.cpp | 31 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index 8a0660823..959d465c0 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -46,13 +46,14 @@ namespace mtconnect::pipeline { auto evt = std::dynamic_pointer_cast(entity); auto di = evt->getDataItem(); - auto &value = evt->getValue(); - if (evt->isUnavailable()) + if (evt->isUnavailable() || di->isDataSet()) { evt->setProperty("quality", std::string("VALID")); } else { + auto &value = evt->getValue(); + // Optimize auto vocab = ControlledVocabularies.find(evt->getName()); if (vocab != ControlledVocabularies.end()) diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index 6ba8dd6cc..a74bb8c9f 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -170,3 +170,34 @@ TEST_F(ObservationValidationTest, should_not_set_deprecated_flag_when_deprecated ASSERT_FALSE(evt->hasProperty("deprecated")); } + + +TEST_F(ObservationValidationTest, should_not_validate_data_sets) +{ + ErrorList errors; + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}, {"representation", "DATA_SET"s}}, errors); + ASSERT_TRUE(m_dataItem->isDataSet()); + + auto event = Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); + +} + +TEST_F(ObservationValidationTest, should_not_validate_tables) +{ + ErrorList errors; + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}, {"representation", "TABLE"s}}, errors); + ASSERT_TRUE(m_dataItem->isDataSet()); + + auto event = Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); + +} From 0c48e4517b9c885615dd21e42ea80eaa6e320ea9 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 14:44:22 -0400 Subject: [PATCH 010/128] Formatted files --- test_package/observation_validation_test.cpp | 23 ++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index a74bb8c9f..c7296ca40 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -171,33 +171,38 @@ TEST_F(ObservationValidationTest, should_not_set_deprecated_flag_when_deprecated ASSERT_FALSE(evt->hasProperty("deprecated")); } - TEST_F(ObservationValidationTest, should_not_validate_data_sets) { ErrorList errors; - m_dataItem = - DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}, {"representation", "DATA_SET"s}}, errors); + m_dataItem = DataItem::make({{"id", "exec"s}, + {"category", "EVENT"s}, + {"type", "EXECUTION"s}, + {"representation", "DATA_SET"s}}, + errors); ASSERT_TRUE(m_dataItem->isDataSet()); - auto event = Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); + auto event = + Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("VALID", quality); - } TEST_F(ObservationValidationTest, should_not_validate_tables) { ErrorList errors; - m_dataItem = - DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}, {"representation", "TABLE"s}}, errors); + m_dataItem = DataItem::make({{"id", "exec"s}, + {"category", "EVENT"s}, + {"type", "EXECUTION"s}, + {"representation", "TABLE"s}}, + errors); ASSERT_TRUE(m_dataItem->isDataSet()); - auto event = Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); + auto event = + Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("VALID", quality); - } From 1e9f542bdbb8ad60152ba6239fb1a1d7375868d7 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 16:06:39 -0400 Subject: [PATCH 011/128] Added some documentation --- src/mtconnect/pipeline/validator.hpp | 8 +++++++- test_package/observation_validation_test.cpp | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index 959d465c0..44c02becf 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -28,7 +28,10 @@ namespace mtconnect::pipeline { using namespace entity; - /// @brief Map a token list to data items or asset types + /// @brief Validate obsrvations based on Controlled Vocabularies + /// + /// - Does not validate data sets and tables + /// - Validates all events, not samples or conditions class AGENT_LIB_API Validator : public Transform { public: @@ -39,6 +42,9 @@ namespace mtconnect::pipeline { m_guard = TypeGuard(RUN) || TypeGuard(SKIP); } + /// @brief validate the Event + /// @param entity The Event entity + /// @returns modified entity with quality and deprecated properties EntityPtr operator()(entity::EntityPtr &&entity) override { using namespace observation; diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index c7296ca40..2c2cb3dcd 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -15,6 +15,9 @@ // limitations under the License. // +/// @file +/// Observation validation tests + // Ensure that gtest is the first header otherwise Windows raises an error #include // Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) @@ -66,6 +69,7 @@ class MockPipelineContract : public PipelineContract int32_t m_schemaVersion; }; +/// @brief Validation tests for observations class ObservationValidationTest : public testing::Test { protected: @@ -95,6 +99,7 @@ class ObservationValidationTest : public testing::Test Timestamp m_time; }; +/// @test Validate a valid value for Execution TEST_F(ObservationValidationTest, should_validate_value) { ErrorList errors; @@ -105,6 +110,7 @@ TEST_F(ObservationValidationTest, should_validate_value) ASSERT_EQ("VALID", quality); } +/// @test Unavailable should always be valid TEST_F(ObservationValidationTest, unavailable_should_be_valid) { ErrorList errors; @@ -114,6 +120,7 @@ TEST_F(ObservationValidationTest, unavailable_should_be_valid) ASSERT_EQ("VALID", quality); } +/// @test Invalid values should be marked as invalid TEST_F(ObservationValidationTest, should_detect_invalid_value) { ErrorList errors; @@ -124,6 +131,7 @@ TEST_F(ObservationValidationTest, should_detect_invalid_value) ASSERT_EQ("INVALID", quality); } +/// @test Unknown types should be unverifiable TEST_F(ObservationValidationTest, should_not_validate_unknown_type) { ErrorList errors; @@ -137,6 +145,7 @@ TEST_F(ObservationValidationTest, should_not_validate_unknown_type) ASSERT_EQ("UNVERIFIABLE", quality); } +/// @test Tag deprecated values TEST_F(ObservationValidationTest, should_set_deprecated_flag_when_deprecated) { ErrorList errors; @@ -153,6 +162,7 @@ TEST_F(ObservationValidationTest, should_set_deprecated_flag_when_deprecated) ASSERT_TRUE(dep); } +/// @test Only deprecate when the version is earlier than the current version TEST_F(ObservationValidationTest, should_not_set_deprecated_flag_when_deprecated_version_greater) { ErrorList errors; @@ -171,6 +181,7 @@ TEST_F(ObservationValidationTest, should_not_set_deprecated_flag_when_deprecated ASSERT_FALSE(evt->hasProperty("deprecated")); } +/// @test do not validate data sets TEST_F(ObservationValidationTest, should_not_validate_data_sets) { ErrorList errors; @@ -189,6 +200,7 @@ TEST_F(ObservationValidationTest, should_not_validate_data_sets) ASSERT_EQ("VALID", quality); } +/// @test do not validate tables TEST_F(ObservationValidationTest, should_not_validate_tables) { ErrorList errors; From 23f95c35e50d578c1794383f0308533a2a341a0a Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 16:21:49 -0400 Subject: [PATCH 012/128] Added documentation for validation namespace --- src/mtconnect/validation/observations.hpp | 27 +++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index 808e0ea01..0eebdbed5 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -22,7 +22,26 @@ #include "../utilities.hpp" -namespace mtconnect::validation::observations { - using Validation = std::unordered_map>; - extern Validation ControlledVocabularies; -} // namespace mtconnect::validation::observations +namespace mtconnect { + + /// @brief MTConnect validation containers + namespace validation { + + /// @brief Observation validation containers + namespace observations { + + /// @brief Validation type for observations + using Validation = std::unordered_map>; + + /// @brief Global Validations for Event Observation's Controlled Vocabularies + /// + /// The map is as follows: + /// * Event name --> + /// * Map of valid values. Empty map if not controlled. + /// * Map has is a pair of value to + /// * 0 if not deprecated + /// * SCHEMA_VERSION if deprecated + extern Validation ControlledVocabularies; + } // namespace observations + } // namespace validation +} // namespace mtconnect From 2b7250672fd3af680e3d7a4553daf948b66b4a65 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 16:49:56 -0400 Subject: [PATCH 013/128] Skip docker build for RC tags --- .github/workflows/build-docker-image.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 6fca33491..947664751 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -32,6 +32,9 @@ on: jobs: # this workflow contains a single job called "build" build: + # Do not build if it is an RC build + if: ${{ ! contains(github.ref_name, "RC") }} + # the type of runner that the job will run on runs-on: ubuntu-latest strategy: From 4dd060246294a9d923cd352d4b20759627df8062 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 17:47:17 -0400 Subject: [PATCH 014/128] upgraded to boost 1.84 --- conan/mqtt_cpp/conanfile.py | 2 +- conanfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conan/mqtt_cpp/conanfile.py b/conan/mqtt_cpp/conanfile.py index 456503ef4..308a349c2 100644 --- a/conan/mqtt_cpp/conanfile.py +++ b/conan/mqtt_cpp/conanfile.py @@ -10,7 +10,7 @@ class MqttcppConan(ConanFile): url = "https://github.com/redboltz/mqtt_cpp" description = "MQTT client/server for C++14 based on Boost.Asio" topics = ("mqtt") - requires = ["boost/1.82.0"] + requires = ["boost/1.84.0"] no_copy_source = True exports_sources = "include/*" diff --git a/conanfile.py b/conanfile.py index 5dfe85877..2c384fb36 100644 --- a/conanfile.py +++ b/conanfile.py @@ -118,7 +118,7 @@ def build_requirements(self): self.tool_requires_version("doxygen", [1, 9, 4]) def requirements(self): - self.requires("boost/1.82.0", headers=True, libs=True, transitive_headers=True, transitive_libs=True) + self.requires("boost/1.84.0", headers=True, libs=True, transitive_headers=True, transitive_libs=True) self.requires("libxml2/2.10.3", headers=True, libs=True, visible=True, transitive_headers=True, transitive_libs=True) self.requires("date/2.4.1", headers=True, libs=True, transitive_headers=True, transitive_libs=True) self.requires("nlohmann_json/3.9.1", headers=True, libs=False, transitive_headers=True, transitive_libs=False) From bca17068736662ca3c6d058c2c7594708a5878d2 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 8 Apr 2024 13:52:13 -0400 Subject: [PATCH 015/128] checkpoint with initial parsing of json --- agent_lib/CMakeLists.txt | 1 + src/mtconnect/sink/rest_sink/request.hpp | 1 + src/mtconnect/sink/rest_sink/session_impl.cpp | 32 +- src/mtconnect/sink/rest_sink/session_impl.hpp | 14 +- .../sink/rest_sink/websocket_session.hpp | 293 ++++++++++++++++++ 5 files changed, 338 insertions(+), 3 deletions(-) create mode 100644 src/mtconnect/sink/rest_sink/websocket_session.hpp diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index ac5763e40..4e0a99701 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -266,6 +266,7 @@ set(AGENT_SOURCES "${SOURCE_DIR}/sink/rest_sink/session.hpp" "${SOURCE_DIR}/sink/rest_sink/session_impl.hpp" "${SOURCE_DIR}/sink/rest_sink/tls_dector.hpp" + "${SOURCE_DIR}/sink/rest_sink/websocket_session.hpp" # src/sink/rest_sink SOURCE_FILES_ONLY diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index f62f37dbe..5271c791c 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -67,6 +67,7 @@ namespace mtconnect::sink::rest_sink { uint16_t m_foreignPort; ///< The requestors Port QueryMap m_query; ///< The parsed query parameters ParameterMap m_parameters; ///< The parsed path parameters + bool m_parsed { false }; ///< Flag the request as parsed /// @brief Find a parameter by type /// @tparam T the type of the parameter diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index 5faa2931e..2ddd38e33 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -34,6 +34,7 @@ #include "request.hpp" #include "response.hpp" #include "tls_dector.hpp" +#include "websocket_session.hpp" namespace mtconnect::sink::rest_sink { namespace beast = boost::beast; // from @@ -248,9 +249,9 @@ namespace mtconnect::sink::rest_sink { if (ws::is_upgrade(msg)) { LOG(debug) << "Upgrading to websocket request"; + upgrade(std::move(msg)); } - - if (!m_dispatch(shared_ptr(), m_request)) + else if (!m_dispatch(shared_ptr(), m_request)) { ostringstream txt; txt << "Failed to find handler for " << msg.method() << " " << msg.target(); @@ -468,6 +469,16 @@ namespace mtconnect::sink::rest_sink { writeResponse(std::move(response)); } } + + SessionPtr HttpSession::upgradeToWebsocket(RequestMessage &&msg) + { + return std::make_shared(std::move(m_stream), + std::move(m_request), + std::move(msg), + m_dispatch, + m_errorFunction); + } + /// @brief A secure https session class HttpsSession : public SessionImpl @@ -525,6 +536,16 @@ namespace mtconnect::sink::rest_sink { m_stream.async_shutdown(beast::bind_front_handler(&HttpsSession::shutdown, shared_ptr())); } } + + /// @brief Upgrade the current connection to a websocket connection. + SessionPtr upgradeToWebsocket(RequestMessage &&msg) + { + return std::make_shared(std::move(m_stream), + std::move(m_request), + std::move(msg), + m_dispatch, + m_errorFunction); + } protected: void handshake(beast::error_code ec, size_t bytes_used) @@ -548,6 +569,13 @@ namespace mtconnect::sink::rest_sink { beast::ssl_stream m_stream; bool m_closing {false}; }; + + template + void SessionImpl::upgrade(RequestMessage &&msg) + { + LOG(debug) << "Upgrading session to websockets"; + derived().upgradeToWebsocket(std::move(msg))->run(); + } void TlsDector::run() { diff --git a/src/mtconnect/sink/rest_sink/session_impl.hpp b/src/mtconnect/sink/rest_sink/session_impl.hpp index 404d25b9c..0d811a84a 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.hpp +++ b/src/mtconnect/sink/rest_sink/session_impl.hpp @@ -35,6 +35,12 @@ namespace mtconnect { } namespace sink::rest_sink { + template + class WebsocketSession; + template + using WebsocketSessionPtr = std::shared_ptr>; + + /// @brief A session implementation `Derived` subclass pattern /// @tparam subclass of this class to use the same methods with http or https protocol streams template @@ -61,7 +67,7 @@ namespace mtconnect { return std::dynamic_pointer_cast(shared_from_this()); } /// @brief get this as the `Derived` type - /// @return + /// @return the subclass Derived &derived() { return static_cast(*this); } /// @name Session Interface @@ -74,6 +80,8 @@ namespace mtconnect { void closeStream() override; ///@} protected: + using RequestMessage = boost::beast::http::request; + template void addHeaders(const Response &response, T &res); @@ -81,6 +89,7 @@ namespace mtconnect { void sent(boost::system::error_code ec, size_t len); void read(); void reset(); + void upgrade(RequestMessage &&msg); protected: using RequestParser = boost::beast::http::request_parser; @@ -144,6 +153,9 @@ namespace mtconnect { boost::beast::error_code ec; m_stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); } + + /// @brief Upgrade the current connection to a websocket connection. + SessionPtr upgradeToWebsocket(RequestMessage &&msg); protected: boost::beast::tcp_stream m_stream; diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp new file mode 100644 index 000000000..2d87ced24 --- /dev/null +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -0,0 +1,293 @@ +// +// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include +#include + +#include +#include + +#include +#include +#include + +#include "mtconnect/config.hpp" +#include "mtconnect/configuration/config_options.hpp" +#include "mtconnect/utilities.hpp" +#include "session.hpp" + +namespace mtconnect::sink::rest_sink { + namespace beast = boost::beast; + + /// @brief A websocket session that provides a pubsub interface using REST parameters + template + class WebsocketSession : public Session + { + public: + using RequestMessage = boost::beast::http::request; + + WebsocketSession(RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) + : Session(dispatch, func), m_request(std::move(request)), m_msg(std::move(msg)) + { + } + + /// @brief Session cannot be copied. + WebsocketSession(const WebsocketSession &) = delete; + ~WebsocketSession() = default; + + /// @brief get this as the `Derived` type + /// @return the subclass + Derived &derived() { return static_cast(*this); } + + + void run() override + { + using namespace boost::beast; + + // Set suggested timeout settings for the websocket + derived().stream().set_option( + websocket::stream_base::timeout::suggested( + beast::role_type::server)); + + // Set a decorator to change the Server of the handshake + derived().stream().set_option( + websocket::stream_base::decorator( + [](websocket::response_type& res) + { + res.set(http::field::server, + GetAgentVersion() + + " MTConnectAgent"); + })); + + // Accept the websocket handshake + derived().stream().async_accept( + m_msg, + beast::bind_front_handler( + &WebsocketSession::onAccept, + derived().shared_ptr())); + } + + void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override + { + + } + + void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override + { + } + + void beginStreaming(const std::string &mimeType, Complete complete) override + { + } + + void writeChunk(const std::string &chunk, Complete complete) override + { + + } + + void closeStream() override + { + } + + protected: + void onAccept(boost::beast::error_code ec) + { + if (ec) + { + fail(status::internal_server_error, "Error occurred in accpet", ec); + return; + } + + derived().stream().async_read( + m_buffer, + beast::bind_front_handler( + &WebsocketSession::onRead, + derived().shared_ptr())); + + } + + void onRead(beast::error_code ec, + std::size_t len) + { + using namespace rapidjson; + using namespace std; + + // Parse the buffer as a JSON request with parameters matching + // REST API + derived().stream().text(derived().stream().got_text()); + auto buffer = beast::buffers_to_string(m_buffer.data()); + + Document doc; + doc.Parse(buffer.c_str(), len); + + if (doc.HasParseError()) + { + LOG(warning) << "Websocket Read Error(offset (" << doc.GetErrorOffset() << "): " << + GetParseError_En(doc.GetParseError()); + LOG(warning) << " " << buffer; + } + if (!doc.IsObject()) + { + LOG(warning) << "Websocket Read Error: JSON message does not have a top level object"; + LOG(warning) << " " << buffer; + } + else + { + // Extract the parameters from the json doc to map them to the REST + // protocol parameters + auto request = std::make_shared(); + request->m_verb = beast::http::verb::get; + const auto &object = doc.GetObject(); + + for (auto &it : object) + { + switch (it.value.GetType()) + { + case rapidjson::kNullType: + // Skip nulls + break; + case rapidjson::kFalseType: + request->m_parameters.emplace(make_pair(it.name.GetString(), false)); + break; + case rapidjson::kTrueType: + request->m_parameters.emplace(make_pair(it.name.GetString(), true)); + break; + case rapidjson::kObjectType: + break; + case rapidjson::kArrayType: + break; + case rapidjson::kStringType: + request->m_parameters.emplace(make_pair(it.name.GetString(), string(it.value.GetString()))); + + break; + case rapidjson::kNumberType: + if (it.value.Is()) + request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + else if (it.value.Is()) + request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + else if (it.value.Is()) + request->m_parameters.emplace(make_pair(it.name.GetString(), (uint64_t) it.value.Get())); + else if (it.value.Is()) + request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + else if (it.value.Is()) + request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + + break; + } + } + + m_request->m_parsed = true; + if (!m_dispatch(derived().shared_ptr(), m_request)) + { + ostringstream txt; + txt << "Failed to find handler for " << buffer; + LOG(error) << txt.str(); + } + } + + derived().stream().async_read( + m_buffer, + beast::bind_front_handler( + &WebsocketSession::onRead, + derived().shared_ptr())); + } + + protected: + RequestPtr m_request; + RequestMessage m_msg; + beast::flat_buffer m_buffer; + }; + + template + using WebsocketSessionPtr = std::shared_ptr>; + + class PlainWebsocketSession : public WebsocketSession + { + public: + using Stream = beast::websocket::stream; + + PlainWebsocketSession(beast::tcp_stream&& stream, RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) + : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) + { + } + ~PlainWebsocketSession() + { + close(); + } + + void close() override + { + NAMED_SCOPE("PlainWebsocketSession::close"); + + m_request.reset(); + m_stream.close(beast::websocket::close_code::none); + } + + auto &stream() { return m_stream; } + + /// @brief Get a pointer cast as an Websocket Session + /// @return shared pointer to an Websocket session + std::shared_ptr shared_ptr() + { + return std::dynamic_pointer_cast(shared_from_this()); + } + + + + protected: + Stream m_stream; + }; + + class TlsWebsocketSession : public WebsocketSession + { + public: + using Stream = beast::websocket::stream>; + + TlsWebsocketSession(beast::ssl_stream&& stream, RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) + : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) + { + } + ~TlsWebsocketSession() + { + close(); + } + + auto &stream() { return m_stream; } + + void close() override + { + NAMED_SCOPE("TlsWebsocketSession::close"); + + m_request.reset(); + m_stream.close(beast::websocket::close_code::none); + } + + /// @brief Get a pointer cast as an TLS Websocket Session + /// @return shared pointer to an TLS Websocket session + std::shared_ptr shared_ptr() + { + return std::dynamic_pointer_cast(shared_from_this()); + } + + protected: + Stream m_stream; + }; + +} + From 7003e19dfea5dc8c4109f96ac07bdb656655016b Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 11 Apr 2024 17:47:25 -0400 Subject: [PATCH 016/128] First steps to adding routing support to websocket request. --- src/mtconnect/sink/rest_sink/request.hpp | 5 ++- src/mtconnect/sink/rest_sink/rest_service.cpp | 16 ++++--- src/mtconnect/sink/rest_sink/rest_service.hpp | 7 --- src/mtconnect/sink/rest_sink/routing.hpp | 21 +++++++-- src/mtconnect/sink/rest_sink/server.hpp | 44 +++++++++++++++---- .../sink/rest_sink/websocket_session.hpp | 6 ++- 6 files changed, 73 insertions(+), 26 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index 9a24e2239..164ddcd33 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -67,7 +67,10 @@ namespace mtconnect::sink::rest_sink { uint16_t m_foreignPort; ///< The requestors Port QueryMap m_query; ///< The parsed query parameters ParameterMap m_parameters; ///< The parsed path parameters - bool m_parsed { false }; ///< Flag the request as parsed + + std::optional m_requestId; ///< Request id from websocket sub + std::optional m_command; ///< Specific request from websocket + /// @brief Find a parameter by type /// @tparam T the type of the parameter diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 9237a4645..6d71d9eae 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -122,7 +122,8 @@ namespace mtconnect { createAssetRoutings(); createPutObservationRoutings(); createFileRoutings(); - + m_server->addCommands(); + makeLoopbackSource(m_sinkContract->m_pipelineContext); } @@ -499,7 +500,8 @@ namespace mtconnect { "/{device}/probe?pretty={bool:false}&deviceType={string}", handler}) .document("MTConnect probe request", "Provides metadata service for the MTConnect Devices information model for " - "device identified by `device` matching `name` or `uuid`."); + "device identified by `device` matching `name` or `uuid`.") + .command("probe"); // Must be last m_server @@ -642,7 +644,9 @@ namespace mtconnect { "/{device}/" + asset + "?type={string}", deleteHandler}) .document("Delete all assets for a device and type", "Device and type are optional. If they are not given, it assumes there is " - "no constraint"); + "no constraint") + .command("asset"); +; } } } @@ -682,7 +686,8 @@ namespace mtconnect { m_server->addRouting({boost::beast::http::verb::get, "/{device}/current?" + qp, handler}) .document("MTConnect current request", "Gets a stapshot of the state of all the observations for device `device` " - "optionally filtered by the `path`"); + "optionally filtered by the `path`") + .command("current"); } void RestService::createSampleRoutings() @@ -727,7 +732,8 @@ namespace mtconnect { .document("MTConnect sample request", "Gets a time series of at maximum `count` observations for device `device` " "optionally filtered by the `path` and starting at `from`. By default, from is " - "the first available observation known to the agent"); + "the first available observation known to the agent") + .command("sample"); } void RestService::createPutObservationRoutings() diff --git a/src/mtconnect/sink/rest_sink/rest_service.hpp b/src/mtconnect/sink/rest_sink/rest_service.hpp index 51505fd51..923f210df 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.hpp +++ b/src/mtconnect/sink/rest_sink/rest_service.hpp @@ -321,22 +321,15 @@ namespace mtconnect { protected: // Loopback boost::asio::io_context &m_context; - boost::asio::io_context::strand m_strand; - std::string m_schemaVersion; - ConfigOptions m_options; - std::shared_ptr m_loopback; - uint64_t m_instanceId; - std::unique_ptr m_server; // Buffers FileCache m_fileCache; - bool m_logStreamData {false}; }; } // namespace sink::rest_sink diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index ca8bdf38d..5b235b56d 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -53,8 +53,8 @@ namespace mtconnect::sink::rest_sink { /// @param[in] function the function to call if matches /// @param[in] swagger `true` if swagger related Routing(boost::beast::http::verb verb, const std::string &pattern, const Function function, - bool swagger = false) - : m_verb(verb), m_function(function), m_swagger(swagger) + bool swagger = false, std::optional request = std::nullopt) + : m_verb(verb), m_command(request), m_function(function), m_swagger(swagger) { std::string s(pattern); @@ -79,8 +79,8 @@ namespace mtconnect::sink::rest_sink { /// @param[in] function the function to call if matches /// @param[in] swagger `true` if swagger related Routing(boost::beast::http::verb verb, const std::regex &pattern, const Function function, - bool swagger = false) - : m_verb(verb), m_pattern(pattern), m_function(function), m_swagger(swagger) + bool swagger = false, std::optional request = std::nullopt) + : m_verb(verb), m_pattern(pattern), m_command(request), m_function(function), m_swagger(swagger) {} /// @brief Added summary and description to the routing @@ -224,6 +224,17 @@ namespace mtconnect::sink::rest_sink { const auto &getPath() const { return m_path; } /// @brief Get the routing `verb` const auto &getVerb() const { return m_verb; } + + /// @brief Get the optional command associated with the routing + /// @returns optional routing + const auto &getCommand() const { return m_command; } + + /// @brief Sets the command associated with this routing for use with websockets + /// @param command the command + void command(const std::string &command) + { + m_command = command; + } protected: void pathParameters(std::string s) @@ -360,7 +371,9 @@ namespace mtconnect::sink::rest_sink { std::optional m_path; ParameterList m_pathParameters; QuerySet m_queryParameters; + std::optional m_command; Function m_function; + std::optional m_summary; std::optional m_description; diff --git a/src/mtconnect/sink/rest_sink/server.hpp b/src/mtconnect/sink/rest_sink/server.hpp index d72fd1764..9e5987aa2 100644 --- a/src/mtconnect/sink/rest_sink/server.hpp +++ b/src/mtconnect/sink/rest_sink/server.hpp @@ -159,16 +159,31 @@ namespace mtconnect::sink::rest_sink { { try { - for (auto &r : m_routings) + if (request->m_command) { - if (r.matches(session, request)) - return true; + auto route = m_commands.find(*request->m_command); + if (route != m_commands.end()) + { + + } + + std::stringstream txt; + txt << session->getRemote().address() << ": Cannot find handler for command: " << *request->m_command; + session->fail(boost::beast::http::status::not_found, txt.str()); + } + else + { + for (auto &r : m_routings) + { + if (r.matches(session, request)) + return true; + } + + std::stringstream txt; + txt << session->getRemote().address() << ": Cannot find handler for: " << request->m_verb + << " " << request->m_path; + session->fail(boost::beast::http::status::not_found, txt.str()); } - - std::stringstream txt; - txt << session->getRemote().address() << ": Cannot find handler for: " << request->m_verb - << " " << request->m_path; - session->fail(boost::beast::http::status::not_found, txt.str()); } catch (RequestError &re) { @@ -217,8 +232,20 @@ namespace mtconnect::sink::rest_sink { auto &route = m_routings.emplace_back(routing); if (m_parameterDocumentation) route.documentParameters(*m_parameterDocumentation); + if (route.getCommand()) + m_commands.emplace(*route.getCommand(), &route); return route; } + + /// @brief Setup commands from routings + void addCommands() + { + for (auto &route : m_routings) + { + if (route.getCommand()) + m_commands.emplace(*route.getCommand(), &route); + } + } /// @brief Add common set of documentation for all rest routings /// @param[in] docs Parameter documentation @@ -272,6 +299,7 @@ namespace mtconnect::sink::rest_sink { std::set m_allowPutsFrom; std::list m_routings; + std::map m_commands; std::unique_ptr m_fileCache; ErrorFunction m_errorFunction; FieldList m_fields; diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 2d87ced24..46043fe20 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -192,7 +192,11 @@ namespace mtconnect::sink::rest_sink { } } - m_request->m_parsed = true; + if (object.HasMember("command")) + request->m_command = object["command"].GetString(); + if (object.HasMember("id")) + request->m_requestId = object["id"].GetString(); + if (!m_dispatch(derived().shared_ptr(), m_request)) { ostringstream txt; From 211f691662ae4403b9b72da8c5ac6caae5550f79 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 12 Apr 2024 12:39:49 -0400 Subject: [PATCH 017/128] Changed from command to request --- src/mtconnect/sink/rest_sink/websocket_session.hpp | 4 ++-- test_package/resources/samples/test_config.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 46043fe20..add1a6d99 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -192,8 +192,8 @@ namespace mtconnect::sink::rest_sink { } } - if (object.HasMember("command")) - request->m_command = object["command"].GetString(); + if (object.HasMember("request")) + request->m_command = object["request"].GetString(); if (object.HasMember("id")) request->m_requestId = object["id"].GetString(); diff --git a/test_package/resources/samples/test_config.xml b/test_package/resources/samples/test_config.xml index b42a291c7..cda9baf07 100644 --- a/test_package/resources/samples/test_config.xml +++ b/test_package/resources/samples/test_config.xml @@ -1,6 +1,6 @@ -
+
Linux CNC Device From e6b4f154ea1b63159f4e3e07a78417a36af702ee Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Tue, 16 Apr 2024 10:11:40 -0400 Subject: [PATCH 018/128] working to the point of response --- README.md | 12 +++- src/mtconnect/sink/rest_sink/routing.hpp | 57 ++++++++++--------- src/mtconnect/sink/rest_sink/server.hpp | 13 +++-- .../sink/rest_sink/websocket_session.hpp | 55 +++++++++++++----- 4 files changed, 90 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 55d322ba2..ef6f285f9 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -MTConnect C++ Agent Version 2.3 +MTConnect C++ Agent Version 2.5 -------- [![Build MTConnect C++ Agent](https://github.com/mtconnect/cppagent/actions/workflows/build.yml/badge.svg)](https://github.com/mtconnect/cppagent/actions/workflows/build.yml) @@ -13,6 +13,10 @@ the devices and the location of the adapter. Pre-built binary releases for Windows are available from [Releases](https://github.com/mtconnect/cppagent/releases) for those who do not want to build the agent themselves. For *NIX users, you will need libxml2, cppunit, and cmake as well as build essentials. +Version 2.5.0 Added validation of observations in the stream + +Version 2.4.0 Added support for version 2.4 + Version 2.3.0 Support for all Version 2.3 standard changes and JSON ingress to MQTT adapter. Version 2.2.0 Support for all Version 2.2 standard changes and dynamic configuration from adapters. Upgrade to conan 2. @@ -639,11 +643,17 @@ Configuration Parameters * `SuppressIPAddress` - Suppress the Adapter IP Address and port when creating the Agent Device ids and names. This applies to all adapters. *Default*: false + +* `Validation` - Turns on validation of model components and observations + + *Default*: false * `WorkerThreads` - The number of operating system threads dedicated to the Agent *Default*: 1 + + #### Adapter General Configuration These can be overridden on a per-adapter basis diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index 5b235b56d..f4048ea1f 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -165,46 +165,49 @@ namespace mtconnect::sink::rest_sink { { try { - request->m_parameters.clear(); - std::smatch m; - if (m_verb == request->m_verb && std::regex_match(request->m_path, m, m_pattern)) + if (!request->m_command) { - auto s = m.begin(); - s++; - for (auto &p : m_pathParameters) + request->m_parameters.clear(); + std::smatch m; + if (m_verb == request->m_verb && std::regex_match(request->m_path, m, m_pattern)) { - if (s != m.end()) + auto s = m.begin(); + s++; + for (auto &p : m_pathParameters) { - ParameterValue v(s->str()); - request->m_parameters.emplace(make_pair(p.m_name, v)); - s++; + if (s != m.end()) + { + ParameterValue v(s->str()); + request->m_parameters.emplace(make_pair(p.m_name, v)); + s++; + } } } + } - for (auto &p : m_queryParameters) + for (auto &p : m_queryParameters) + { + auto q = request->m_query.find(p.m_name); + if (q != request->m_query.end()) { - auto q = request->m_query.find(p.m_name); - if (q != request->m_query.end()) + try { - try - { - auto v = convertValue(q->second, p.m_type); - request->m_parameters.emplace(make_pair(p.m_name, v)); - } - catch (ParameterError &e) - { - std::string msg = - std::string("for query parameter '") + p.m_name + "': " + e.what(); - throw ParameterError(msg); - } + auto v = convertValue(q->second, p.m_type); + request->m_parameters.emplace(make_pair(p.m_name, v)); } - else if (!std::holds_alternative(p.m_default)) + catch (ParameterError &e) { - request->m_parameters.emplace(make_pair(p.m_name, p.m_default)); + std::string msg = + std::string("for query parameter '") + p.m_name + "': " + e.what(); + throw ParameterError(msg); } } - return m_function(session, request); + else if (!std::holds_alternative(p.m_default)) + { + request->m_parameters.emplace(make_pair(p.m_name, p.m_default)); + } } + return m_function(session, request); } catch (ParameterError &e) diff --git a/src/mtconnect/sink/rest_sink/server.hpp b/src/mtconnect/sink/rest_sink/server.hpp index 9e5987aa2..2adde6599 100644 --- a/src/mtconnect/sink/rest_sink/server.hpp +++ b/src/mtconnect/sink/rest_sink/server.hpp @@ -164,12 +164,15 @@ namespace mtconnect::sink::rest_sink { auto route = m_commands.find(*request->m_command); if (route != m_commands.end()) { - + if (route->second->matches(session, request)) + return true; + } + else + { + std::stringstream txt; + txt << session->getRemote().address() << ": Cannot find handler for command: " << *request->m_command; + session->fail(boost::beast::http::status::not_found, txt.str()); } - - std::stringstream txt; - txt << session->getRemote().address() << ": Cannot find handler for command: " << *request->m_command; - session->fail(boost::beast::http::status::not_found, txt.str()); } else { diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index add1a6d99..aabb473f1 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -85,7 +85,17 @@ namespace mtconnect::sink::rest_sink { void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { + beast::flat_buffer buf; + buf.prepare(response->m_body.size()); + buf. + + ws_.async_write( + buf.data(), + beast::bind_front_handler( + &WebsocketSession::sent, + derived().shared_ptr())); + } void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override @@ -122,6 +132,12 @@ namespace mtconnect::sink::rest_sink { } + void sent(beast::error_code ec, + std::size_t len) + { + + } + void onRead(beast::error_code ec, std::size_t len) { @@ -132,6 +148,7 @@ namespace mtconnect::sink::rest_sink { // REST API derived().stream().text(derived().stream().got_text()); auto buffer = beast::buffers_to_string(m_buffer.data()); + m_buffer.consume(m_buffer.size()); Document doc; doc.Parse(buffer.c_str(), len); @@ -151,8 +168,7 @@ namespace mtconnect::sink::rest_sink { { // Extract the parameters from the json doc to map them to the REST // protocol parameters - auto request = std::make_shared(); - request->m_verb = beast::http::verb::get; + m_request->m_verb = beast::http::verb::get; const auto &object = doc.GetObject(); for (auto &it : object) @@ -163,39 +179,50 @@ namespace mtconnect::sink::rest_sink { // Skip nulls break; case rapidjson::kFalseType: - request->m_parameters.emplace(make_pair(it.name.GetString(), false)); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), false)); break; case rapidjson::kTrueType: - request->m_parameters.emplace(make_pair(it.name.GetString(), true)); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), true)); break; case rapidjson::kObjectType: break; case rapidjson::kArrayType: break; case rapidjson::kStringType: - request->m_parameters.emplace(make_pair(it.name.GetString(), string(it.value.GetString()))); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), string(it.value.GetString()))); break; case rapidjson::kNumberType: if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), (uint64_t) it.value.Get())); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), (uint64_t) it.value.Get())); else if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); break; } } - if (object.HasMember("request")) - request->m_command = object["request"].GetString(); - if (object.HasMember("id")) - request->m_requestId = object["id"].GetString(); + if (m_request->m_parameters.count("request") > 0) + { + m_request->m_command = get(m_request->m_parameters["request"]); + m_request->m_parameters.erase("request"); + } + if (m_request->m_parameters.count("id") > 0) + { + auto &v =m_request->m_parameters["id"]; + string id = visit(overloaded { + [](monostate m) { return ""s; }, + [](auto v) { return boost::lexical_cast(v); } + }, v); + m_request->m_requestId = id; + m_request->m_parameters.erase("id"); + } if (!m_dispatch(derived().shared_ptr(), m_request)) { From f7802f7d90916e8df02eb9fba45c42e5154fb45f Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Tue, 16 Apr 2024 14:56:08 -0400 Subject: [PATCH 019/128] checkpoint with write response --- src/mtconnect/mqtt/mqtt_client_impl.hpp | 8 +- src/mtconnect/sink/rest_sink/request.hpp | 5 +- src/mtconnect/sink/rest_sink/response.hpp | 1 + src/mtconnect/sink/rest_sink/rest_service.cpp | 58 ++-- src/mtconnect/sink/rest_sink/routing.hpp | 19 +- src/mtconnect/sink/rest_sink/server.hpp | 9 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 27 +- src/mtconnect/sink/rest_sink/session_impl.hpp | 9 +- .../sink/rest_sink/websocket_session.hpp | 272 ++++++++++-------- src/mtconnect/validation/observations.hpp | 6 +- 10 files changed, 221 insertions(+), 193 deletions(-) diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index 56eb701ce..3e166dc61 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -164,7 +164,7 @@ namespace mtconnect { m_connected = false; if (m_handler && m_handler->m_disconnected) m_handler->m_disconnected(shared_from_this()); - m_handler->m_disconnected(shared_from_this()); + m_handler->m_disconnected(shared_from_this()); if (m_running) { reconnect(); @@ -419,7 +419,7 @@ namespace mtconnect { { return static_pointer_cast(shared_from_this()); } - + /// @brief Get the Mqtt TCP Client /// @return pointer to the Mqtt TCP Client auto &getClient() @@ -501,7 +501,7 @@ namespace mtconnect { { return static_pointer_cast(shared_from_this()); } - + /// @brief Get the Mqtt TLS WebSocket Client /// @return pointer to the Mqtt TLS WebSocket Client auto &getClient() @@ -540,7 +540,7 @@ namespace mtconnect { { return static_pointer_cast(shared_from_this()); } - + /// @brief Get the Mqtt TLS WebSocket Client /// @return pointer to the Mqtt TLS WebSocket Client auto &getClient() diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index 164ddcd33..ac3f2c33b 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -68,9 +68,8 @@ namespace mtconnect::sink::rest_sink { QueryMap m_query; ///< The parsed query parameters ParameterMap m_parameters; ///< The parsed path parameters - std::optional m_requestId; ///< Request id from websocket sub - std::optional m_command; ///< Specific request from websocket - + std::optional m_requestId; ///< Request id from websocket sub + std::optional m_command; ///< Specific request from websocket /// @brief Find a parameter by type /// @tparam T the type of the parameter diff --git a/src/mtconnect/sink/rest_sink/response.hpp b/src/mtconnect/sink/rest_sink/response.hpp index a67bdbe6b..b19fecff1 100644 --- a/src/mtconnect/sink/rest_sink/response.hpp +++ b/src/mtconnect/sink/rest_sink/response.hpp @@ -64,6 +64,7 @@ namespace mtconnect { std::chrono::seconds m_expires; ///< how long should this session should stay open before it is closed bool m_close {false}; ///< `true` if this session should closed after it responds + std::optional m_requestId; ///< Request id from websocket sub CachedFilePtr m_file; ///< Cached file if a file is being returned }; diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 6d71d9eae..dee758bae 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -123,7 +123,7 @@ namespace mtconnect { createPutObservationRoutings(); createFileRoutings(); m_server->addCommands(); - + makeLoopbackSource(m_sinkContract->m_pipelineContext); } @@ -435,8 +435,10 @@ namespace mtconnect { // Request Routings // ----------------------------------------------------------- - static inline void respond(rest_sink::SessionPtr session, rest_sink::ResponsePtr &&response) + static inline void respond(rest_sink::SessionPtr session, rest_sink::ResponsePtr &&response, + std::optional id = std::nullopt) { + response->m_requestId = id; session->writeResponse(std::move(response)); } @@ -485,7 +487,7 @@ namespace mtconnect { return false; } - respond(session, probeRequest(printer, device, pretty, deviceType)); + respond(session, probeRequest(printer, device, pretty, deviceType), request->m_requestId); return true; }; @@ -526,8 +528,10 @@ namespace mtconnect { auto count = *request->parameter("count"); auto printer = printerForAccepts(request->m_accepts); - respond(session, assetRequest(printer, count, removed, request->parameter("type"), - request->parameter("device"))); + respond(session, + assetRequest(printer, count, removed, request->parameter("type"), + request->parameter("device")), + request->m_requestId); return true; }; @@ -542,14 +546,15 @@ namespace mtconnect { string id; while (getline(str, id, ';')) ids.emplace_back(id); - respond(session, assetIdsRequest(printer, ids)); + respond(session, assetIdsRequest(printer, ids), request->m_requestId); } else { auto printer = printerForAccepts(request->m_accepts); auto error = printError(printer, "INVALID_REQUEST", "No asset given"); - respond(session, make_unique(rest_sink::status::bad_request, error, - printer->mimeType())); + respond(session, + make_unique(rest_sink::status::bad_request, error, printer->mimeType()), + request->m_requestId); } return true; }; @@ -581,7 +586,8 @@ namespace mtconnect { respond(session, putAssetRequest(printer, request->m_body, request->parameter("type"), request->parameter("device"), - request->parameter("assetId"))); + request->parameter("assetId")), + request->m_requestId); return true; }; @@ -596,13 +602,15 @@ namespace mtconnect { while (getline(str, id, ';')) ids.emplace_back(id); - respond(session, deleteAssetRequest(printer, ids)); + respond(session, deleteAssetRequest(printer, ids), request->m_requestId); } else { - respond(session, deleteAllAssetsRequest(printerForAccepts(request->m_accepts), - request->parameter("device"), - request->parameter("type"))); + respond(session, + deleteAllAssetsRequest(printerForAccepts(request->m_accepts), + request->parameter("device"), + request->parameter("type")), + request->m_requestId); } return true; }; @@ -646,7 +654,7 @@ namespace mtconnect { "Device and type are optional. If they are not given, it assumes there is " "no constraint") .command("asset"); -; + ; } } } @@ -665,12 +673,13 @@ namespace mtconnect { } else { - respond(session, currentRequest(printerForAccepts(request->m_accepts), - request->parameter("device"), - request->parameter("at"), - request->parameter("path"), - *request->parameter("pretty"), - request->parameter("deviceType"))); + respond( + session, + currentRequest( + printerForAccepts(request->m_accepts), request->parameter("device"), + request->parameter("at"), request->parameter("path"), + *request->parameter("pretty"), request->parameter("deviceType")), + request->m_requestId); } return true; }; @@ -712,7 +721,8 @@ namespace mtconnect { printerForAccepts(request->m_accepts), *request->parameter("count"), request->parameter("device"), request->parameter("from"), request->parameter("to"), request->parameter("path"), - *request->parameter("pretty"), request->parameter("deviceType"))); + *request->parameter("pretty"), request->parameter("deviceType")), + request->m_requestId); } return true; }; @@ -751,8 +761,10 @@ namespace mtconnect { queries.erase("time"); auto device = request->parameter("device"); - respond(session, putObservationRequest(printerForAccepts(request->m_accepts), *device, - queries, ts)); + respond( + session, + putObservationRequest(printerForAccepts(request->m_accepts), *device, queries, ts), + request->m_requestId); return true; } else diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index f4048ea1f..230534222 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -80,7 +80,11 @@ namespace mtconnect::sink::rest_sink { /// @param[in] swagger `true` if swagger related Routing(boost::beast::http::verb verb, const std::regex &pattern, const Function function, bool swagger = false, std::optional request = std::nullopt) - : m_verb(verb), m_pattern(pattern), m_command(request), m_function(function), m_swagger(swagger) + : m_verb(verb), + m_pattern(pattern), + m_command(request), + m_function(function), + m_swagger(swagger) {} /// @brief Added summary and description to the routing @@ -197,8 +201,7 @@ namespace mtconnect::sink::rest_sink { } catch (ParameterError &e) { - std::string msg = - std::string("for query parameter '") + p.m_name + "': " + e.what(); + std::string msg = std::string("for query parameter '") + p.m_name + "': " + e.what(); throw ParameterError(msg); } } @@ -227,17 +230,14 @@ namespace mtconnect::sink::rest_sink { const auto &getPath() const { return m_path; } /// @brief Get the routing `verb` const auto &getVerb() const { return m_verb; } - + /// @brief Get the optional command associated with the routing /// @returns optional routing const auto &getCommand() const { return m_command; } - + /// @brief Sets the command associated with this routing for use with websockets /// @param command the command - void command(const std::string &command) - { - m_command = command; - } + void command(const std::string &command) { m_command = command; } protected: void pathParameters(std::string s) @@ -376,7 +376,6 @@ namespace mtconnect::sink::rest_sink { QuerySet m_queryParameters; std::optional m_command; Function m_function; - std::optional m_summary; std::optional m_description; diff --git a/src/mtconnect/sink/rest_sink/server.hpp b/src/mtconnect/sink/rest_sink/server.hpp index 2adde6599..740efab83 100644 --- a/src/mtconnect/sink/rest_sink/server.hpp +++ b/src/mtconnect/sink/rest_sink/server.hpp @@ -170,7 +170,8 @@ namespace mtconnect::sink::rest_sink { else { std::stringstream txt; - txt << session->getRemote().address() << ": Cannot find handler for command: " << *request->m_command; + txt << session->getRemote().address() + << ": Cannot find handler for command: " << *request->m_command; session->fail(boost::beast::http::status::not_found, txt.str()); } } @@ -184,7 +185,7 @@ namespace mtconnect::sink::rest_sink { std::stringstream txt; txt << session->getRemote().address() << ": Cannot find handler for: " << request->m_verb - << " " << request->m_path; + << " " << request->m_path; session->fail(boost::beast::http::status::not_found, txt.str()); } } @@ -239,7 +240,7 @@ namespace mtconnect::sink::rest_sink { m_commands.emplace(*route.getCommand(), &route); return route; } - + /// @brief Setup commands from routings void addCommands() { @@ -302,7 +303,7 @@ namespace mtconnect::sink::rest_sink { std::set m_allowPutsFrom; std::list m_routings; - std::map m_commands; + std::map m_commands; std::unique_ptr m_fileCache; ErrorFunction m_errorFunction; FieldList m_fields; diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index 52651e384..d84c43fd7 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -198,7 +198,7 @@ namespace mtconnect::sink::rest_sink { auto &msg = m_parser->get(); const auto &remote = beast::get_lowest_layer(derived().stream()).socket().remote_endpoint(); - + // Check for put, post, or delete if (msg.method() != http::verb::get) { @@ -244,7 +244,7 @@ namespace mtconnect::sink::rest_sink { LOG(info) << "ReST Request: From [" << m_request->m_foreignIp << ':' << remote.port() << "]: " << msg.method() << " " << msg.target(); - + // Check if this is a websocket upgrade request. If so, begin a websocket session. if (ws::is_upgrade(msg)) { @@ -469,17 +469,13 @@ namespace mtconnect::sink::rest_sink { writeResponse(std::move(response)); } } - + SessionPtr HttpSession::upgradeToWebsocket(RequestMessage &&msg) { - return std::make_shared(std::move(m_stream), - std::move(m_request), - std::move(msg), - m_dispatch, - m_errorFunction); + return std::make_shared(std::move(m_stream), std::move(m_request), + std::move(msg), m_dispatch, m_errorFunction); } - /// @brief A secure https session class HttpsSession : public SessionImpl { @@ -536,15 +532,12 @@ namespace mtconnect::sink::rest_sink { m_stream.async_shutdown(beast::bind_front_handler(&HttpsSession::shutdown, shared_ptr())); } } - + /// @brief Upgrade the current connection to a websocket connection. SessionPtr upgradeToWebsocket(RequestMessage &&msg) { - return std::make_shared(std::move(m_stream), - std::move(m_request), - std::move(msg), - m_dispatch, - m_errorFunction); + return std::make_shared(std::move(m_stream), std::move(m_request), + std::move(msg), m_dispatch, m_errorFunction); } protected: @@ -569,8 +562,8 @@ namespace mtconnect::sink::rest_sink { beast::ssl_stream m_stream; bool m_closing {false}; }; - - template + + template void SessionImpl::upgrade(RequestMessage &&msg) { LOG(debug) << "Upgrading session to websockets"; diff --git a/src/mtconnect/sink/rest_sink/session_impl.hpp b/src/mtconnect/sink/rest_sink/session_impl.hpp index 27be34970..07ab7fbd0 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.hpp +++ b/src/mtconnect/sink/rest_sink/session_impl.hpp @@ -35,12 +35,11 @@ namespace mtconnect { } namespace sink::rest_sink { - template + template class WebsocketSession; - template + template using WebsocketSessionPtr = std::shared_ptr>; - - + /// @brief A session implementation `Derived` subclass pattern /// @tparam subclass of this class to use the same methods with http or https protocol streams template @@ -153,7 +152,7 @@ namespace mtconnect { boost::beast::error_code ec; m_stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); } - + /// @brief Upgrade the current connection to a websocket connection. SessionPtr upgradeToWebsocket(RequestMessage &&msg); diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index aabb473f1..f39b559e5 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -20,12 +20,11 @@ #include #include -#include -#include - #include #include #include +#include +#include #include "mtconnect/config.hpp" #include "mtconnect/configuration/config_options.hpp" @@ -34,18 +33,26 @@ namespace mtconnect::sink::rest_sink { namespace beast = boost::beast; - + + struct WebsocketRequest + { + std::string m_requestId; + std::optional m_streamBuffer; + Complete m_complete; + bool m_streaming {false}; + }; + /// @brief A websocket session that provides a pubsub interface using REST parameters - template + template class WebsocketSession : public Session { public: using RequestMessage = boost::beast::http::request; - WebsocketSession(RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) - : Session(dispatch, func), m_request(std::move(request)), m_msg(std::move(msg)) - { - } + WebsocketSession(RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, + ErrorFunction func) + : Session(dispatch, func), m_request(std::move(request)), m_msg(std::move(msg)) + {} /// @brief Session cannot be copied. WebsocketSession(const WebsocketSession &) = delete; @@ -54,67 +61,69 @@ namespace mtconnect::sink::rest_sink { /// @brief get this as the `Derived` type /// @return the subclass Derived &derived() { return static_cast(*this); } - - + void run() override { using namespace boost::beast; - + // Set suggested timeout settings for the websocket derived().stream().set_option( - websocket::stream_base::timeout::suggested( - beast::role_type::server)); + websocket::stream_base::timeout::suggested(beast::role_type::server)); // Set a decorator to change the Server of the handshake derived().stream().set_option( - websocket::stream_base::decorator( - [](websocket::response_type& res) - { - res.set(http::field::server, - GetAgentVersion() + - " MTConnectAgent"); + websocket::stream_base::decorator([](websocket::response_type &res) { + res.set(http::field::server, GetAgentVersion() + " MTConnectAgent"); })); // Accept the websocket handshake derived().stream().async_accept( - m_msg, - beast::bind_front_handler( - &WebsocketSession::onAccept, - derived().shared_ptr())); + m_msg, beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr())); } void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { - beast::flat_buffer buf; - - buf.prepare(response->m_body.size()); - buf. - - ws_.async_write( - buf.data(), - beast::bind_front_handler( - &WebsocketSession::sent, - derived().shared_ptr())); + if (response->m_requestId) + { + auto id = *(response->m_requestId); + auto it = m_requests.find(id); + if (it != m_requests.end()) + { + using namespace std::placeholders; + auto &req = it->second; + req.m_complete = complete; + req.m_streamBuffer.emplace(); + std::ostream str(&req.m_streamBuffer.value()); + + str << response->m_body; + + derived().stream().text(derived().stream().got_text()); + derived().stream().async_write( + req.m_streamBuffer->data(), + beast::bind_handler( + [this, id](beast::error_code ec, std::size_t len) { sent(ec, len, id); }, _1, + _2)); + } + else + { + LOG(error) << "WebsocketSession::writeResponse: Cannot find request for id: " << id; + } + } + else + { + LOG(error) << "WebsocketSession::writeResponse: No request id for websocket"; + } } - - void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override - { - } - - void beginStreaming(const std::string &mimeType, Complete complete) override - { - } - - void writeChunk(const std::string &chunk, Complete complete) override - { - - } - - void closeStream() override - { - } - + + void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override {} + + void beginStreaming(const std::string &mimeType, Complete complete) override {} + + void writeChunk(const std::string &chunk, Complete complete) override {} + + void closeStream() override {} + protected: void onAccept(boost::beast::error_code ec) { @@ -123,40 +132,54 @@ namespace mtconnect::sink::rest_sink { fail(status::internal_server_error, "Error occurred in accpet", ec); return; } - - derived().stream().async_read( - m_buffer, - beast::bind_front_handler( - &WebsocketSession::onRead, - derived().shared_ptr())); + derived().stream().async_read( + m_buffer, beast::bind_front_handler(&WebsocketSession::onRead, derived().shared_ptr())); } - - void sent(beast::error_code ec, - std::size_t len) + + void sent(beast::error_code ec, std::size_t len, const std::string &id) { - + auto it = m_requests.find(id); + if (it != m_requests.end()) + { + auto &req = it->second; + if (req.m_complete) + { + req.m_complete(); + } + + if (!req.m_streaming) + { + m_requests.erase(id); + } + } + else + { + LOG(error) << "WebsocketSession::sent: Cannot find request for id: " << id; + } } - - void onRead(beast::error_code ec, - std::size_t len) + + void onRead(beast::error_code ec, std::size_t len) { + if (ec) + return fail(boost::beast::http::status::internal_server_error, "shutdown", ec); + using namespace rapidjson; using namespace std; - + // Parse the buffer as a JSON request with parameters matching // REST API derived().stream().text(derived().stream().got_text()); auto buffer = beast::buffers_to_string(m_buffer.data()); m_buffer.consume(m_buffer.size()); - + Document doc; doc.Parse(buffer.c_str(), len); - + if (doc.HasParseError()) { - LOG(warning) << "Websocket Read Error(offset (" << doc.GetErrorOffset() << "): " << - GetParseError_En(doc.GetParseError()); + LOG(warning) << "Websocket Read Error(offset (" << doc.GetErrorOffset() + << "): " << GetParseError_En(doc.GetParseError()); LOG(warning) << " " << buffer; } if (!doc.IsObject()) @@ -170,7 +193,7 @@ namespace mtconnect::sink::rest_sink { // protocol parameters m_request->m_verb = beast::http::verb::get; const auto &object = doc.GetObject(); - + for (auto &it : object) { switch (it.value.GetType()) @@ -185,29 +208,35 @@ namespace mtconnect::sink::rest_sink { m_request->m_parameters.emplace(make_pair(it.name.GetString(), true)); break; case rapidjson::kObjectType: - break; + break; case rapidjson::kArrayType: break; case rapidjson::kStringType: - m_request->m_parameters.emplace(make_pair(it.name.GetString(), string(it.value.GetString()))); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), string(it.value.GetString()))); break; case rapidjson::kNumberType: if (it.value.Is()) - m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace(make_pair(it.name.GetString(), (uint64_t) it.value.Get())); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), (uint64_t)it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), it.value.Get())); break; } } - + if (m_request->m_parameters.count("request") > 0) { m_request->m_command = get(m_request->m_parameters["request"]); @@ -215,15 +244,17 @@ namespace mtconnect::sink::rest_sink { } if (m_request->m_parameters.count("id") > 0) { - auto &v =m_request->m_parameters["id"]; - string id = visit(overloaded { - [](monostate m) { return ""s; }, - [](auto v) { return boost::lexical_cast(v); } - }, v); + auto &v = m_request->m_parameters["id"]; + string id = visit(overloaded {[](monostate m) { return ""s; }, + [](auto v) { return boost::lexical_cast(v); }}, + v); m_request->m_requestId = id; m_request->m_parameters.erase("id"); } + auto &req = m_requests[*(m_request->m_requestId)]; + req.m_requestId = *(m_request->m_requestId); + if (!m_dispatch(derived().shared_ptr(), m_request)) { ostringstream txt; @@ -231,45 +262,42 @@ namespace mtconnect::sink::rest_sink { LOG(error) << txt.str(); } } - + derived().stream().async_read( - m_buffer, - beast::bind_front_handler( - &WebsocketSession::onRead, - derived().shared_ptr())); + m_buffer, beast::bind_front_handler(&WebsocketSession::onRead, derived().shared_ptr())); } - + protected: RequestPtr m_request; RequestMessage m_msg; beast::flat_buffer m_buffer; + std::map m_requests; }; - - template + + template using WebsocketSessionPtr = std::shared_ptr>; - + class PlainWebsocketSession : public WebsocketSession { public: using Stream = beast::websocket::stream; - - PlainWebsocketSession(beast::tcp_stream&& stream, RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) - : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) - { - } - ~PlainWebsocketSession() - { - close(); - } - + + PlainWebsocketSession(beast::tcp_stream &&stream, RequestPtr &&request, RequestMessage &&msg, + Dispatch dispatch, ErrorFunction func) + : WebsocketSession(std::move(request), std::move(msg), dispatch, func), + m_stream(std::move(stream)) + {} + ~PlainWebsocketSession() { close(); } + void close() override { NAMED_SCOPE("PlainWebsocketSession::close"); - + m_request.reset(); - m_stream.close(beast::websocket::close_code::none); + if (m_stream.is_open()) + m_stream.close(beast::websocket::close_code::none); } - + auto &stream() { return m_stream; } /// @brief Get a pointer cast as an Websocket Session @@ -278,37 +306,34 @@ namespace mtconnect::sink::rest_sink { { return std::dynamic_pointer_cast(shared_from_this()); } - - - + protected: Stream m_stream; }; - + class TlsWebsocketSession : public WebsocketSession { public: using Stream = beast::websocket::stream>; - - TlsWebsocketSession(beast::ssl_stream&& stream, RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) - : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) - { - } - ~TlsWebsocketSession() - { - close(); - } + + TlsWebsocketSession(beast::ssl_stream &&stream, RequestPtr &&request, + RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) + : WebsocketSession(std::move(request), std::move(msg), dispatch, func), + m_stream(std::move(stream)) + {} + ~TlsWebsocketSession() { close(); } auto &stream() { return m_stream; } - + void close() override { NAMED_SCOPE("TlsWebsocketSession::close"); m_request.reset(); - m_stream.close(beast::websocket::close_code::none); + if (m_stream.is_open()) + m_stream.close(beast::websocket::close_code::none); } - + /// @brief Get a pointer cast as an TLS Websocket Session /// @return shared pointer to an TLS Websocket session std::shared_ptr shared_ptr() @@ -319,6 +344,5 @@ namespace mtconnect::sink::rest_sink { protected: Stream m_stream; }; - -} +} // namespace mtconnect::sink::rest_sink diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index 0eebdbed5..c5a843edd 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -23,13 +23,13 @@ #include "../utilities.hpp" namespace mtconnect { - + /// @brief MTConnect validation containers namespace validation { - + /// @brief Observation validation containers namespace observations { - + /// @brief Validation type for observations using Validation = std::unordered_map>; From 51c57b967dc6d28842a52a9f8aa47ded54194e72 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 18 Apr 2024 22:36:26 -0400 Subject: [PATCH 020/128] Handled threading issues and send queue --- src/mtconnect/observation/change_observer.cpp | 4 + src/mtconnect/sink/rest_sink/rest_service.cpp | 28 ++- src/mtconnect/sink/rest_sink/rest_service.hpp | 6 +- src/mtconnect/sink/rest_sink/session.hpp | 5 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 4 +- src/mtconnect/sink/rest_sink/session_impl.hpp | 5 +- .../sink/rest_sink/websocket_session.hpp | 209 ++++++++++++++---- 7 files changed, 206 insertions(+), 55 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index 88b5c5da4..dde38e9a3 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -145,9 +145,12 @@ namespace mtconnect::observation { void AsyncObserver::handlerCompleted() { + NAMED_SCOPE("AsyncObserver::handlerCompleted"); + m_last = std::chrono::system_clock::now(); if (m_endOfBuffer) { + LOG(trace) << "End of buffer"; using std::placeholders::_1; m_observer.waitForSignal(m_heartbeat); } @@ -159,6 +162,7 @@ namespace mtconnect::observation { void AsyncObserver::handleSignal(boost::system::error_code ec) { + NAMED_SCOPE("AsyncObserver::handleSignal"); using namespace buffer; using std::placeholders::_1; diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index dee758bae..5cb1f3a02 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -669,7 +669,8 @@ namespace mtconnect { streamCurrentRequest( session, printerForAccepts(request->m_accepts), *interval, request->parameter("device"), request->parameter("path"), - *request->parameter("pretty"), request->parameter("deviceType")); + *request->parameter("pretty"), request->parameter("deviceType"), + request->m_requestId); } else { @@ -711,7 +712,8 @@ namespace mtconnect { *request->parameter("heartbeat"), *request->parameter("count"), request->parameter("device"), request->parameter("from"), request->parameter("path"), *request->parameter("pretty"), - request->parameter("deviceType")); + request->parameter("deviceType"), + request->m_requestId); } else { @@ -932,6 +934,7 @@ namespace mtconnect { rest_sink::SessionPtr m_session; ofstream m_log; bool m_pretty {false}; + std::optional m_requestId; }; void RestService::streamSampleRequest(rest_sink::SessionPtr session, const Printer *printer, @@ -939,7 +942,8 @@ namespace mtconnect { const int count, const std::optional &device, const std::optional &from, const std::optional &path, bool pretty, - const std::optional &deviceType) + const std::optional &deviceType, + const std::optional &requestId) { NAMED_SCOPE("RestService::streamSampleRequest"); @@ -973,6 +977,7 @@ namespace mtconnect { asyncResponse->m_printer = printer; asyncResponse->m_sink = getptr(); asyncResponse->m_pretty = pretty; + asyncResponse->m_requestId = requestId; if (m_logStreamData) { @@ -990,7 +995,8 @@ namespace mtconnect { session->beginStreaming( printer->mimeType(), asio::bind_executor(m_strand, - boost::bind(&AsyncObserver::handlerCompleted, asyncResponse))); + boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), + requestId); } SequenceNumber_t RestService::streamNextSampleChunk( @@ -1021,7 +1027,9 @@ namespace mtconnect { asyncResponse->m_session->writeChunk( content, asio::bind_executor( - m_strand, boost::bind(&AsyncObserver::handlerCompleted, asyncResponse))); + m_strand, boost::bind(&AsyncObserver::handlerCompleted, asyncResponse) + ), + asyncResponse->m_requestId); return end; } @@ -1059,13 +1067,15 @@ namespace mtconnect { FilterSetOpt m_filter; boost::asio::steady_timer m_timer; bool m_pretty {false}; + std::optional m_requestId; }; void RestService::streamCurrentRequest(SessionPtr session, const Printer *printer, const int interval, const std::optional &device, const std::optional &path, bool pretty, - const std::optional &deviceType) + const std::optional &deviceType, + const std::optional &requestId) { checkRange(printer, interval, 0, numeric_limits().max(), "interval"); DevicePtr dev {nullptr}; @@ -1084,11 +1094,13 @@ namespace mtconnect { asyncResponse->m_printer = printer; asyncResponse->m_service = getptr(); asyncResponse->m_pretty = pretty; + asyncResponse->m_requestId = requestId; asyncResponse->m_session->beginStreaming( printer->mimeType(), boost::asio::bind_executor(m_strand, [this, asyncResponse]() { streamNextCurrent(asyncResponse, boost::system::error_code {}); - })); + }), + requestId); } void RestService::streamNextCurrent(std::shared_ptr asyncResponse, @@ -1127,7 +1139,7 @@ namespace mtconnect { asyncResponse->m_timer.expires_from_now(asyncResponse->m_interval); asyncResponse->m_timer.async_wait(boost::asio::bind_executor( m_strand, boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); - })); + }), asyncResponse->m_requestId); } catch (RequestError &re) { diff --git a/src/mtconnect/sink/rest_sink/rest_service.hpp b/src/mtconnect/sink/rest_sink/rest_service.hpp index 923f210df..934231443 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.hpp +++ b/src/mtconnect/sink/rest_sink/rest_service.hpp @@ -149,7 +149,8 @@ namespace mtconnect { const std::optional &from = std::nullopt, const std::optional &path = std::nullopt, bool pretty = false, - const std::optional &deviceType = std::nullopt); + const std::optional &deviceType = std::nullopt, + const std::optional &responseId = std::nullopt); /// @brief Handler for a streaming current /// @param[in] session session to stream data to @@ -162,7 +163,8 @@ namespace mtconnect { const std::optional &device = std::nullopt, const std::optional &path = std::nullopt, bool pretty = false, - const std::optional &deviceType = std::nullopt); + const std::optional &deviceType = std::nullopt, + const std::optional &responseId = std::nullopt); /// @brief Handler for put/post observation /// @param[in] p printer for response generation /// @param[in] device device diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index c4ed9041a..dcb30e911 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -64,11 +64,12 @@ namespace mtconnect::sink::rest_sink { /// @brief begin streaming data to the client using x-multipart-replace /// @param mimeType the mime type of the response /// @param complete completion callback - virtual void beginStreaming(const std::string &mimeType, Complete complete) = 0; + virtual void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) = 0; /// @brief write a chunk for a streaming session /// @param chunk the chunk to write /// @param complete a completion callback - virtual void writeChunk(const std::string &chunk, Complete complete) = 0; + virtual void writeChunk(const std::string &chunk, Complete complete, + std::optional requestId = std::nullopt) = 0; /// @brief close the session virtual void close() = 0; /// @brief close the stream diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index d84c43fd7..cce9a9881 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -287,7 +287,7 @@ namespace mtconnect::sink::rest_sink { } template - void SessionImpl::beginStreaming(const std::string &mimeType, Complete complete) + void SessionImpl::beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId) { NAMED_SCOPE("SessionImpl::beginStreaming"); @@ -321,7 +321,7 @@ namespace mtconnect::sink::rest_sink { } template - void SessionImpl::writeChunk(const std::string &body, Complete complete) + void SessionImpl::writeChunk(const std::string &body, Complete complete, std::optional requestId) { NAMED_SCOPE("SessionImpl::writeChunk"); diff --git a/src/mtconnect/sink/rest_sink/session_impl.hpp b/src/mtconnect/sink/rest_sink/session_impl.hpp index 07ab7fbd0..2c046171a 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.hpp +++ b/src/mtconnect/sink/rest_sink/session_impl.hpp @@ -74,8 +74,9 @@ namespace mtconnect { void run() override; void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override; void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override; - void beginStreaming(const std::string &mimeType, Complete complete) override; - void writeChunk(const std::string &chunk, Complete complete) override; + void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) override; + void writeChunk(const std::string &chunk, Complete complete, + std::optional requestId = std::nullopt) override; void closeStream() override; ///@} protected: diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index f39b559e5..c580facf3 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,8 @@ namespace mtconnect::sink::rest_sink { struct WebsocketRequest { + WebsocketRequest(const std::string &id) + : m_requestId(id) { } std::string m_requestId; std::optional m_streamBuffer; Complete m_complete; @@ -46,6 +49,19 @@ namespace mtconnect::sink::rest_sink { template class WebsocketSession : public Session { + protected: + struct Message { + Message(const std::string &body, Complete &complete, + const std::string &requestId) + : m_body(body), m_complete(complete), m_requestId(requestId) + { + } + + std::string m_body; + Complete m_complete; + std::string m_requestId; + }; + public: using RequestMessage = boost::beast::http::request; @@ -69,7 +85,7 @@ namespace mtconnect::sink::rest_sink { // Set suggested timeout settings for the websocket derived().stream().set_option( websocket::stream_base::timeout::suggested(beast::role_type::server)); - + // Set a decorator to change the Server of the handshake derived().stream().set_option( websocket::stream_base::decorator([](websocket::response_type &res) { @@ -78,51 +94,78 @@ namespace mtconnect::sink::rest_sink { // Accept the websocket handshake derived().stream().async_accept( - m_msg, beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr())); + m_msg, boost::asio::bind_executor(derived().getExecutor(), beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr()))); } void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { - if (response->m_requestId) + NAMED_SCOPE("WebsocketSession::writeResponse"); + if (!response->m_requestId) { - auto id = *(response->m_requestId); + boost::system::error_code ec; + return fail(status::bad_request, "Missing request Id", ec); + } + + writeChunk(response->m_body, complete, response->m_requestId); + } + + void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override + { + NAMED_SCOPE("WebsocketSession::writeFailureResponse"); + writeChunk(response->m_body, complete, response->m_requestId); + } + + void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) override + { + if (requestId) + { + auto id = *(requestId); auto it = m_requests.find(id); if (it != m_requests.end()) { - using namespace std::placeholders; - auto &req = it->second; - req.m_complete = complete; - req.m_streamBuffer.emplace(); - std::ostream str(&req.m_streamBuffer.value()); - - str << response->m_body; - - derived().stream().text(derived().stream().got_text()); - derived().stream().async_write( - req.m_streamBuffer->data(), - beast::bind_handler( - [this, id](beast::error_code ec, std::size_t len) { sent(ec, len, id); }, _1, - _2)); + req.m_streaming = true; + + if (complete) + complete(); } else { - LOG(error) << "WebsocketSession::writeResponse: Cannot find request for id: " << id; + LOG(error) << "Cannot find request for id: " << id; } } else { - LOG(error) << "WebsocketSession::writeResponse: No request id for websocket"; + LOG(error) << "No request id for websocket"; } } - void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override {} - - void beginStreaming(const std::string &mimeType, Complete complete) override {} - - void writeChunk(const std::string &chunk, Complete complete) override {} + void writeChunk(const std::string &chunk, Complete complete, std::optional requestId = std::nullopt) override + { + NAMED_SCOPE("WebsocketSession::writeChunk"); + if (requestId) + { + LOG(trace) << "Waiting for mutex"; + std::lock_guard lock(m_mutex); + + if (m_busy) + { + m_messageQueue.emplace_back(chunk, complete, *requestId); + } + else + { + send(chunk, complete, *requestId); + } + } + else + { + LOG(error) << "No request id for websocket"; + } + } - void closeStream() override {} + void closeStream() override + { + } protected: void onAccept(boost::beast::error_code ec) @@ -136,31 +179,101 @@ namespace mtconnect::sink::rest_sink { derived().stream().async_read( m_buffer, beast::bind_front_handler(&WebsocketSession::onRead, derived().shared_ptr())); } - - void sent(beast::error_code ec, std::size_t len, const std::string &id) + + void send(const std::string body, Complete complete, const std::string &requestId) { - auto it = m_requests.find(id); + NAMED_SCOPE("WebsocketSession::send"); + + using namespace std::placeholders; + + auto it = m_requests.find(requestId); if (it != m_requests.end()) { auto &req = it->second; - if (req.m_complete) + req.m_complete = complete; + req.m_streamBuffer.emplace(); + std::ostream str(&req.m_streamBuffer.value()); + + str << body; + + auto ref = derived().shared_ptr(); + + LOG(trace) << "writing chunk for ws: " << requestId; + + m_busy = true; + + derived().stream().text(derived().stream().got_text()); + derived().stream().async_write( + req.m_streamBuffer->data(), + beast::bind_handler( + [ref, requestId](beast::error_code ec, std::size_t len) { ref->sent(ec, len, requestId); }, _1, + _2)); + } + else + { + LOG(error) << "Cannot find request for id: " << requestId; + } + } + + void sent(beast::error_code ec, std::size_t len, const std::string &id) + { + NAMED_SCOPE("WebsocketSession::sent"); + + if (ec) + { + return fail(status::bad_request, "Missing request Id", ec); + } + + { + LOG(trace) << "Waiting for mutex"; + std::lock_guard lock(m_mutex); + + LOG(trace) << "sent chunk for ws: " << id; + + auto it = m_requests.find(id); + if (it != m_requests.end()) { - req.m_complete(); + auto &req = it->second; + if (req.m_complete) + { + boost::asio::post(derived().stream().get_executor(), + req.m_complete); + } + + if (!req.m_streaming) + { + m_requests.erase(id); + } + + if (m_messageQueue.size() == 0) + { + m_busy = false; + } } - - if (!req.m_streaming) + else { - m_requests.erase(id); + LOG(error) << "WebsocketSession::sent: Cannot find request for id: " << id; } } - else + { - LOG(error) << "WebsocketSession::sent: Cannot find request for id: " << id; + LOG(trace) << "Waiting for mutex to send next"; + std::lock_guard lock(m_mutex); + + // Check for queued messages + if (m_messageQueue.size() > 0) + { + auto &msg = m_messageQueue.front(); + send(msg.m_body, msg.m_complete, msg.m_requestId); + m_messageQueue.pop_front(); + } } } void onRead(beast::error_code ec, std::size_t len) { + NAMED_SCOPE("PlainWebsocketSession::onRead"); + if (ec) return fail(boost::beast::http::status::internal_server_error, "shutdown", ec); @@ -252,9 +365,16 @@ namespace mtconnect::sink::rest_sink { m_request->m_parameters.erase("id"); } - auto &req = m_requests[*(m_request->m_requestId)]; - req.m_requestId = *(m_request->m_requestId); - + auto &id = *(m_request->m_requestId); + + auto res = m_requests.emplace(id, id); + if (!res.second) + { + LOG(error) << "Duplicate request id: " << id; + boost::system::error_code ec; + return fail(status::bad_request, "Duplicate request Id", ec); + } + if (!m_dispatch(derived().shared_ptr(), m_request)) { ostringstream txt; @@ -272,6 +392,9 @@ namespace mtconnect::sink::rest_sink { RequestMessage m_msg; beast::flat_buffer m_buffer; std::map m_requests; + std::mutex m_mutex; + std::atomic_bool m_busy; + std::deque m_messageQueue; }; template @@ -297,6 +420,10 @@ namespace mtconnect::sink::rest_sink { if (m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } + + auto getExecutor() { + return m_stream.get_executor(); + } auto &stream() { return m_stream; } @@ -324,6 +451,10 @@ namespace mtconnect::sink::rest_sink { ~TlsWebsocketSession() { close(); } auto &stream() { return m_stream; } + + auto getExecutor() { + return m_stream.get_executor(); + } void close() override { From 558d625bc547f4a08861d641c351d7c0a778e0ff Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 18 Apr 2024 22:51:13 -0400 Subject: [PATCH 021/128] fixed expiry timeout --- src/mtconnect/sink/rest_sink/websocket_session.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index c580facf3..11bea0441 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -409,7 +409,9 @@ namespace mtconnect::sink::rest_sink { Dispatch dispatch, ErrorFunction func) : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) - {} + { + beast::get_lowest_layer(m_stream).expires_never(); + } ~PlainWebsocketSession() { close(); } void close() override @@ -447,7 +449,9 @@ namespace mtconnect::sink::rest_sink { RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) - {} + { + beast::get_lowest_layer(m_stream).expires_never(); + } ~TlsWebsocketSession() { close(); } auto &stream() { return m_stream; } From 70f1ec1954f0e91fd8df4e7b6c8b66aab30d9be9 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 18 Apr 2024 22:53:46 -0400 Subject: [PATCH 022/128] Formatted new code --- src/mtconnect/observation/change_observer.cpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 48 +++++---- src/mtconnect/sink/rest_sink/session.hpp | 3 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 6 +- src/mtconnect/sink/rest_sink/session_impl.hpp | 3 +- .../sink/rest_sink/websocket_session.hpp | 100 +++++++++--------- 6 files changed, 84 insertions(+), 78 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index dde38e9a3..e186a592b 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -146,7 +146,7 @@ namespace mtconnect::observation { void AsyncObserver::handlerCompleted() { NAMED_SCOPE("AsyncObserver::handlerCompleted"); - + m_last = std::chrono::system_clock::now(); if (m_endOfBuffer) { diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 5cb1f3a02..10e4d478a 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -666,11 +666,11 @@ namespace mtconnect { auto interval = request->parameter("interval"); if (interval) { - streamCurrentRequest( - session, printerForAccepts(request->m_accepts), *interval, - request->parameter("device"), request->parameter("path"), - *request->parameter("pretty"), request->parameter("deviceType"), - request->m_requestId); + streamCurrentRequest(session, printerForAccepts(request->m_accepts), *interval, + request->parameter("device"), + request->parameter("path"), + *request->parameter("pretty"), + request->parameter("deviceType"), request->m_requestId); } else { @@ -712,8 +712,7 @@ namespace mtconnect { *request->parameter("heartbeat"), *request->parameter("count"), request->parameter("device"), request->parameter("from"), request->parameter("path"), *request->parameter("pretty"), - request->parameter("deviceType"), - request->m_requestId); + request->parameter("deviceType"), request->m_requestId); } else { @@ -996,7 +995,7 @@ namespace mtconnect { printer->mimeType(), asio::bind_executor(m_strand, boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), - requestId); + requestId); } SequenceNumber_t RestService::streamNextSampleChunk( @@ -1026,10 +1025,10 @@ namespace mtconnect { asyncResponse->m_log << content << endl; asyncResponse->m_session->writeChunk( - content, asio::bind_executor( - m_strand, boost::bind(&AsyncObserver::handlerCompleted, asyncResponse) - ), - asyncResponse->m_requestId); + content, + asio::bind_executor(m_strand, + boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), + asyncResponse->m_requestId); return end; } @@ -1097,10 +1096,13 @@ namespace mtconnect { asyncResponse->m_requestId = requestId; asyncResponse->m_session->beginStreaming( - printer->mimeType(), boost::asio::bind_executor(m_strand, [this, asyncResponse]() { - streamNextCurrent(asyncResponse, boost::system::error_code {}); - }), - requestId); + printer->mimeType(), + boost::asio::bind_executor(m_strand, + [this, asyncResponse]() { + streamNextCurrent(asyncResponse, + boost::system::error_code {}); + }), + requestId); } void RestService::streamNextCurrent(std::shared_ptr asyncResponse, @@ -1135,11 +1137,15 @@ namespace mtconnect { asyncResponse->m_session->writeChunk( fetchCurrentData(asyncResponse->m_printer, asyncResponse->m_filter, nullopt, asyncResponse->m_pretty), - boost::asio::bind_executor(m_strand, [this, asyncResponse]() { - asyncResponse->m_timer.expires_from_now(asyncResponse->m_interval); - asyncResponse->m_timer.async_wait(boost::asio::bind_executor( - m_strand, boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); - }), asyncResponse->m_requestId); + boost::asio::bind_executor( + m_strand, + [this, asyncResponse]() { + asyncResponse->m_timer.expires_from_now(asyncResponse->m_interval); + asyncResponse->m_timer.async_wait(boost::asio::bind_executor( + m_strand, + boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); + }), + asyncResponse->m_requestId); } catch (RequestError &re) { diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index dcb30e911..4e2bc52ab 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -64,7 +64,8 @@ namespace mtconnect::sink::rest_sink { /// @brief begin streaming data to the client using x-multipart-replace /// @param mimeType the mime type of the response /// @param complete completion callback - virtual void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) = 0; + virtual void beginStreaming(const std::string &mimeType, Complete complete, + std::optional requestId = std::nullopt) = 0; /// @brief write a chunk for a streaming session /// @param chunk the chunk to write /// @param complete a completion callback diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index cce9a9881..40777da00 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -287,7 +287,8 @@ namespace mtconnect::sink::rest_sink { } template - void SessionImpl::beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId) + void SessionImpl::beginStreaming(const std::string &mimeType, Complete complete, + std::optional requestId) { NAMED_SCOPE("SessionImpl::beginStreaming"); @@ -321,7 +322,8 @@ namespace mtconnect::sink::rest_sink { } template - void SessionImpl::writeChunk(const std::string &body, Complete complete, std::optional requestId) + void SessionImpl::writeChunk(const std::string &body, Complete complete, + std::optional requestId) { NAMED_SCOPE("SessionImpl::writeChunk"); diff --git a/src/mtconnect/sink/rest_sink/session_impl.hpp b/src/mtconnect/sink/rest_sink/session_impl.hpp index 2c046171a..b890a6039 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.hpp +++ b/src/mtconnect/sink/rest_sink/session_impl.hpp @@ -74,7 +74,8 @@ namespace mtconnect { void run() override; void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override; void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override; - void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) override; + void beginStreaming(const std::string &mimeType, Complete complete, + std::optional requestId = std::nullopt) override; void writeChunk(const std::string &chunk, Complete complete, std::optional requestId = std::nullopt) override; void closeStream() override; diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 11bea0441..bd7d321fe 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -22,8 +22,8 @@ #include #include -#include #include +#include #include #include @@ -37,8 +37,7 @@ namespace mtconnect::sink::rest_sink { struct WebsocketRequest { - WebsocketRequest(const std::string &id) - : m_requestId(id) { } + WebsocketRequest(const std::string &id) : m_requestId(id) {} std::string m_requestId; std::optional m_streamBuffer; Complete m_complete; @@ -50,18 +49,17 @@ namespace mtconnect::sink::rest_sink { class WebsocketSession : public Session { protected: - struct Message { - Message(const std::string &body, Complete &complete, - const std::string &requestId) - : m_body(body), m_complete(complete), m_requestId(requestId) - { - } - + struct Message + { + Message(const std::string &body, Complete &complete, const std::string &requestId) + : m_body(body), m_complete(complete), m_requestId(requestId) + {} + std::string m_body; Complete m_complete; std::string m_requestId; }; - + public: using RequestMessage = boost::beast::http::request; @@ -85,7 +83,7 @@ namespace mtconnect::sink::rest_sink { // Set suggested timeout settings for the websocket derived().stream().set_option( websocket::stream_base::timeout::suggested(beast::role_type::server)); - + // Set a decorator to change the Server of the handshake derived().stream().set_option( websocket::stream_base::decorator([](websocket::response_type &res) { @@ -94,7 +92,9 @@ namespace mtconnect::sink::rest_sink { // Accept the websocket handshake derived().stream().async_accept( - m_msg, boost::asio::bind_executor(derived().getExecutor(), beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr()))); + m_msg, boost::asio::bind_executor(derived().getExecutor(), + beast::bind_front_handler(&WebsocketSession::onAccept, + derived().shared_ptr()))); } void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override @@ -109,13 +109,14 @@ namespace mtconnect::sink::rest_sink { writeChunk(response->m_body, complete, response->m_requestId); } - void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override + void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override { NAMED_SCOPE("WebsocketSession::writeFailureResponse"); writeChunk(response->m_body, complete, response->m_requestId); } - void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) override + void beginStreaming(const std::string &mimeType, Complete complete, + std::optional requestId = std::nullopt) override { if (requestId) { @@ -125,7 +126,7 @@ namespace mtconnect::sink::rest_sink { { auto &req = it->second; req.m_streaming = true; - + if (complete) complete(); } @@ -140,14 +141,15 @@ namespace mtconnect::sink::rest_sink { } } - void writeChunk(const std::string &chunk, Complete complete, std::optional requestId = std::nullopt) override + void writeChunk(const std::string &chunk, Complete complete, + std::optional requestId = std::nullopt) override { NAMED_SCOPE("WebsocketSession::writeChunk"); if (requestId) { LOG(trace) << "Waiting for mutex"; std::lock_guard lock(m_mutex); - + if (m_busy) { m_messageQueue.emplace_back(chunk, complete, *requestId); @@ -163,9 +165,7 @@ namespace mtconnect::sink::rest_sink { } } - void closeStream() override - { - } + void closeStream() override {} protected: void onAccept(boost::beast::error_code ec) @@ -179,13 +179,13 @@ namespace mtconnect::sink::rest_sink { derived().stream().async_read( m_buffer, beast::bind_front_handler(&WebsocketSession::onRead, derived().shared_ptr())); } - + void send(const std::string body, Complete complete, const std::string &requestId) { NAMED_SCOPE("WebsocketSession::send"); using namespace std::placeholders; - + auto it = m_requests.find(requestId); if (it != m_requests.end()) { @@ -193,21 +193,22 @@ namespace mtconnect::sink::rest_sink { req.m_complete = complete; req.m_streamBuffer.emplace(); std::ostream str(&req.m_streamBuffer.value()); - + str << body; - + auto ref = derived().shared_ptr(); - + LOG(trace) << "writing chunk for ws: " << requestId; - + m_busy = true; - + derived().stream().text(derived().stream().got_text()); - derived().stream().async_write( - req.m_streamBuffer->data(), + derived().stream().async_write(req.m_streamBuffer->data(), beast::bind_handler( - [ref, requestId](beast::error_code ec, std::size_t len) { ref->sent(ec, len, requestId); }, _1, - _2)); + [ref, requestId](beast::error_code ec, std::size_t len) { + ref->sent(ec, len, requestId); + }, + _1, _2)); } else { @@ -218,33 +219,32 @@ namespace mtconnect::sink::rest_sink { void sent(beast::error_code ec, std::size_t len, const std::string &id) { NAMED_SCOPE("WebsocketSession::sent"); - + if (ec) { return fail(status::bad_request, "Missing request Id", ec); } - + { LOG(trace) << "Waiting for mutex"; std::lock_guard lock(m_mutex); LOG(trace) << "sent chunk for ws: " << id; - + auto it = m_requests.find(id); if (it != m_requests.end()) { auto &req = it->second; if (req.m_complete) { - boost::asio::post(derived().stream().get_executor(), - req.m_complete); + boost::asio::post(derived().stream().get_executor(), req.m_complete); } - + if (!req.m_streaming) { m_requests.erase(id); } - + if (m_messageQueue.size() == 0) { m_busy = false; @@ -255,11 +255,11 @@ namespace mtconnect::sink::rest_sink { LOG(error) << "WebsocketSession::sent: Cannot find request for id: " << id; } } - + { LOG(trace) << "Waiting for mutex to send next"; std::lock_guard lock(m_mutex); - + // Check for queued messages if (m_messageQueue.size() > 0) { @@ -273,7 +273,7 @@ namespace mtconnect::sink::rest_sink { void onRead(beast::error_code ec, std::size_t len) { NAMED_SCOPE("PlainWebsocketSession::onRead"); - + if (ec) return fail(boost::beast::http::status::internal_server_error, "shutdown", ec); @@ -366,7 +366,7 @@ namespace mtconnect::sink::rest_sink { } auto &id = *(m_request->m_requestId); - + auto res = m_requests.emplace(id, id); if (!res.second) { @@ -374,7 +374,7 @@ namespace mtconnect::sink::rest_sink { boost::system::error_code ec; return fail(status::bad_request, "Duplicate request Id", ec); } - + if (!m_dispatch(derived().shared_ptr(), m_request)) { ostringstream txt; @@ -422,10 +422,8 @@ namespace mtconnect::sink::rest_sink { if (m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } - - auto getExecutor() { - return m_stream.get_executor(); - } + + auto getExecutor() { return m_stream.get_executor(); } auto &stream() { return m_stream; } @@ -455,10 +453,8 @@ namespace mtconnect::sink::rest_sink { ~TlsWebsocketSession() { close(); } auto &stream() { return m_stream; } - - auto getExecutor() { - return m_stream.get_executor(); - } + + auto getExecutor() { return m_stream.get_executor(); } void close() override { From 8877c03ea5bde604f02a90fc9160b76103aeaa29 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 19 Apr 2024 11:13:26 -0400 Subject: [PATCH 023/128] Working version with error handling --- .../sink/rest_sink/websocket_session.hpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index bd7d321fe..fcf91939e 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -150,7 +150,7 @@ namespace mtconnect::sink::rest_sink { LOG(trace) << "Waiting for mutex"; std::lock_guard lock(m_mutex); - if (m_busy) + if (m_busy || m_messageQueue.size() > 0) { m_messageQueue.emplace_back(chunk, complete, *requestId); } @@ -165,8 +165,6 @@ namespace mtconnect::sink::rest_sink { } } - void closeStream() override {} - protected: void onAccept(boost::beast::error_code ec) { @@ -372,7 +370,7 @@ namespace mtconnect::sink::rest_sink { { LOG(error) << "Duplicate request id: " << id; boost::system::error_code ec; - return fail(status::bad_request, "Duplicate request Id", ec); + fail(status::bad_request, "Duplicate request Id", ec); } if (!m_dispatch(derived().shared_ptr(), m_request)) @@ -380,6 +378,8 @@ namespace mtconnect::sink::rest_sink { ostringstream txt; txt << "Failed to find handler for " << buffer; LOG(error) << txt.str(); + boost::system::error_code ec; + fail(status::bad_request, "Duplicate request Id", ec); } } @@ -419,10 +419,16 @@ namespace mtconnect::sink::rest_sink { NAMED_SCOPE("PlainWebsocketSession::close"); m_request.reset(); + closeStream(); + } + + void closeStream() override + { if (m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } + auto getExecutor() { return m_stream.get_executor(); } auto &stream() { return m_stream; } @@ -461,6 +467,11 @@ namespace mtconnect::sink::rest_sink { NAMED_SCOPE("TlsWebsocketSession::close"); m_request.reset(); + closeStream(); + } + + void closeStream() override + { if (m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } From 20ce83abf1339a360de72cf29a9043b59f330c65 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 19 Apr 2024 11:36:37 -0400 Subject: [PATCH 024/128] Added request id to the printers for XML --- src/mtconnect/printer/json_printer.cpp | 12 +++-- src/mtconnect/printer/json_printer.hpp | 12 +++-- src/mtconnect/printer/printer.hpp | 15 ++++--- src/mtconnect/printer/xml_printer.cpp | 27 ++++++++---- src/mtconnect/printer/xml_printer.hpp | 13 +++--- src/mtconnect/sink/rest_sink/rest_service.cpp | 44 ++++++++++++------- src/mtconnect/sink/rest_sink/rest_service.hpp | 28 +++++++----- 7 files changed, 98 insertions(+), 53 deletions(-) diff --git a/src/mtconnect/printer/json_printer.cpp b/src/mtconnect/printer/json_printer.cpp index 287203797..c604a6536 100644 --- a/src/mtconnect/printer/json_printer.cpp +++ b/src/mtconnect/printer/json_printer.cpp @@ -113,7 +113,8 @@ namespace mtconnect::printer { std::string JsonPrinter::printErrors(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty) const + bool pretty, + const std::optional requestId) const { defaultSchemaVersion(); @@ -170,7 +171,8 @@ namespace mtconnect::printer { const unsigned int assetCount, const std::list &devices, const std::map *count, - bool includeHidden, bool pretty) const + bool includeHidden, bool pretty, + const std::optional requestId) const { defaultSchemaVersion(); @@ -197,7 +199,8 @@ namespace mtconnect::printer { std::string JsonPrinter::printAssets(const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetCount, const asset::AssetList &asset, - bool pretty) const + bool pretty, + const std::optional requestId) const { defaultSchemaVersion(); @@ -397,7 +400,8 @@ namespace mtconnect::printer { std::string JsonPrinter::printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, ObservationList &observations, - bool pretty) const + bool pretty, + const std::optional requestId) const { defaultSchemaVersion(); diff --git a/src/mtconnect/printer/json_printer.hpp b/src/mtconnect/printer/json_printer.hpp index fd392133a..102cf51ec 100644 --- a/src/mtconnect/printer/json_printer.hpp +++ b/src/mtconnect/printer/json_printer.hpp @@ -32,21 +32,25 @@ namespace mtconnect::printer { std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false) const override; + bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string printProbe(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const unsigned int assetBufferSize, const unsigned int assetCount, const std::list &devices, const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false) const override; + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, - bool pretty = false) const override; + bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, const asset::AssetList &asset, - bool pretty = false) const override; + bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string mimeType() const override { return "application/mtconnect+json"; } uint32_t getJsonVersion() const { return m_jsonVersion; } diff --git a/src/mtconnect/printer/printer.hpp b/src/mtconnect/printer/printer.hpp index 52943c175..38727109f 100644 --- a/src/mtconnect/printer/printer.hpp +++ b/src/mtconnect/printer/printer.hpp @@ -63,7 +63,8 @@ namespace mtconnect { /// @return the error document virtual std::string printError(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const std::string &errorCode, - const std::string &errorText, bool pretty = false) const + const std::string &errorText, bool pretty = false, + const std::optional requestId = std::nullopt) const { return printErrors(instanceId, bufferSize, nextSeq, {{errorCode, errorText}}); } @@ -75,7 +76,8 @@ namespace mtconnect { /// @return the MTConnect Error document virtual std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false) const = 0; + bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief Generate an MTConnect Devices document /// @param[in] instanceId the instance id /// @param[in] bufferSize the buffer size @@ -90,7 +92,8 @@ namespace mtconnect { const unsigned int assetCount, const std::list &devices, const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false) const = 0; + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief Print a MTConnect Streams document /// @param[in] instanceId the instance id /// @param[in] bufferSize the buffer size @@ -102,7 +105,8 @@ namespace mtconnect { virtual std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, - bool pretty = false) const = 0; + bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief Generate an MTConnect Assets document /// @param[in] anInstanceId the instance id /// @param[in] bufferSize the buffer size @@ -111,7 +115,8 @@ namespace mtconnect { /// @return the MTConnect Assets document virtual std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, asset::AssetList const &asset, - bool pretty = false) const = 0; + bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief get the mime type for the documents /// @return the mime type virtual std::string mimeType() const = 0; diff --git a/src/mtconnect/printer/xml_printer.cpp b/src/mtconnect/printer/xml_printer.cpp index 56e059470..2e5badb39 100644 --- a/src/mtconnect/printer/xml_printer.cpp +++ b/src/mtconnect/printer/xml_printer.cpp @@ -344,7 +344,7 @@ namespace mtconnect::printer { std::string XmlPrinter::printErrors(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty) const + bool pretty, const std::optional requestId) const { string ret; @@ -352,7 +352,8 @@ namespace mtconnect::printer { { XmlWriter writer(m_pretty || pretty); - initXmlDoc(writer, eERROR, instanceId, bufferSize, 0, 0, nextSeq, nextSeq - 1); + initXmlDoc(writer, eERROR, instanceId, bufferSize, 0, 0, nextSeq, 0, nextSeq - 1, + nullptr, requestId); { AutoElement e1(writer, "Errors"); @@ -382,7 +383,7 @@ namespace mtconnect::printer { const uint64_t nextSeq, const unsigned int assetBufferSize, const unsigned int assetCount, const list &deviceList, const std::map *count, bool includeHidden, - bool pretty) const + bool pretty, const std::optional requestId) const { string ret; @@ -391,7 +392,7 @@ namespace mtconnect::printer { XmlWriter writer(m_pretty || pretty); initXmlDoc(writer, eDEVICES, instanceId, bufferSize, assetBufferSize, assetCount, nextSeq, 0, - nextSeq - 1, count); + nextSeq - 1, count, requestId); { AutoElement devices(writer, "Devices"); @@ -419,7 +420,7 @@ namespace mtconnect::printer { string XmlPrinter::printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, ObservationList &observations, - bool pretty) const + bool pretty, const std::optional requestId) const { string ret; @@ -427,7 +428,8 @@ namespace mtconnect::printer { { XmlWriter writer(m_pretty || pretty); - initXmlDoc(writer, eSTREAMS, instanceId, bufferSize, 0, 0, nextSeq, firstSeq, lastSeq); + initXmlDoc(writer, eSTREAMS, instanceId, bufferSize, 0, 0, nextSeq, firstSeq, lastSeq, + nullptr, requestId); AutoElement streams(writer, "Streams"); @@ -499,13 +501,15 @@ namespace mtconnect::printer { string XmlPrinter::printAssets(const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetCount, const AssetList &asset, - bool pretty) const + bool pretty, + const std::optional requestId) const { string ret; try { XmlWriter writer(m_pretty || pretty); - initXmlDoc(writer, eASSETS, instanceId, 0u, bufferSize, assetCount, 0ull); + initXmlDoc(writer, eASSETS, instanceId, 0u, bufferSize, assetCount, 0ull, + 0, 0, nullptr, requestId); { AutoElement ele(writer, "Assets"); @@ -541,7 +545,8 @@ namespace mtconnect::printer { const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetBufferSize, const unsigned int assetCount, const uint64_t nextSeq, const uint64_t firstSeq, - const uint64_t lastSeq, const map *count) const + const uint64_t lastSeq, const map *count, + const std::optional requestId) const { THROW_IF_XML2_ERROR(xmlTextWriterStartDocument(writer, nullptr, "UTF-8", nullptr)); @@ -647,6 +652,10 @@ namespace mtconnect::printer { sprintf(version, "%d.%d.%d.%d", AGENT_VERSION_MAJOR, AGENT_VERSION_MINOR, AGENT_VERSION_PATCH, AGENT_VERSION_BUILD); addAttribute(writer, "version", version); + + if (requestId) + addAttribute(writer, "requestId", *requestId); + int major, minor; char c; diff --git a/src/mtconnect/printer/xml_printer.hpp b/src/mtconnect/printer/xml_printer.hpp index 781a297cb..337f1fae8 100644 --- a/src/mtconnect/printer/xml_printer.hpp +++ b/src/mtconnect/printer/xml_printer.hpp @@ -45,21 +45,23 @@ namespace mtconnect { std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false) const override; + bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string printProbe(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const unsigned int assetBufferSize, const unsigned int assetCount, const std::list &devices, const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false) const override; + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, - bool pretty = false) const override; + bool pretty = false, const std::optional requestId = std::nullopt) const override; std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, const asset::AssetList &asset, - bool pretty = false) const override; + bool pretty = false, const std::optional requestId = std::nullopt) const override; std::string mimeType() const override { return "text/xml"; } /// @brief Add a Devices XML device namespace @@ -167,7 +169,8 @@ namespace mtconnect { const unsigned int bufferSize, const unsigned int assetBufferSize, const unsigned int assetCount, const uint64_t nextSeq, const uint64_t firstSeq = 0, const uint64_t lastSeq = 0, - const std::map *counts = nullptr) const; + const std::map *counts = nullptr, + const std::optional requestId = std::nullopt) const; // Helper to print individual components and details void printProbeHelper(xmlTextWriterPtr writer, device_model::ComponentPtr component, diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 10e4d478a..fb9951d5d 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -795,7 +795,8 @@ namespace mtconnect { ResponsePtr RestService::probeRequest(const Printer *printer, const std::optional &device, bool pretty, - const std::optional &deviceType) + const std::optional &deviceType, + const std::optional &requestId) { NAMED_SCOPE("RestService::probeRequest"); @@ -832,7 +833,8 @@ namespace mtconnect { const std::optional &device, const std::optional &at, const std::optional &path, bool pretty, - const std::optional &deviceType) + const std::optional &deviceType, + const std::optional &requestId) { using namespace rest_sink; DevicePtr dev {nullptr}; @@ -858,7 +860,8 @@ namespace mtconnect { const std::optional &from, const std::optional &to, const std::optional &path, bool pretty, - const std::optional &deviceType) + const std::optional &deviceType, + const std::optional &requestId) { using namespace rest_sink; DevicePtr dev {nullptr}; @@ -1019,7 +1022,8 @@ namespace mtconnect { string content = fetchSampleData(asyncResponse->m_printer, asyncResponse->getFilter(), asyncResponse->m_count, from, nullopt, end, - asyncObserver->m_endOfBuffer, asyncResponse->m_pretty); + asyncObserver->m_endOfBuffer, asyncResponse->m_pretty, + asyncResponse->m_requestId); if (m_logStreamData) asyncResponse->m_log << content << endl; @@ -1136,7 +1140,7 @@ namespace mtconnect { asyncResponse->m_session->writeChunk( fetchCurrentData(asyncResponse->m_printer, asyncResponse->m_filter, nullopt, - asyncResponse->m_pretty), + asyncResponse->m_pretty, asyncResponse->m_requestId), boost::asio::bind_executor( m_strand, [this, asyncResponse]() { @@ -1168,7 +1172,8 @@ namespace mtconnect { ResponsePtr RestService::assetRequest(const Printer *printer, const int32_t count, const bool removed, const std::optional &type, - const std::optional &device, bool pretty) + const std::optional &device, bool pretty, + const std::optional &requestId) { using namespace rest_sink; @@ -1186,12 +1191,13 @@ namespace mtconnect { status::ok, printer->printAssets( m_instanceId, uint32_t(m_sinkContract->getAssetStorage()->getMaxAssets()), - uint32_t(m_sinkContract->getAssetStorage()->getCount()), list, pretty), + uint32_t(m_sinkContract->getAssetStorage()->getCount()), list, pretty, requestId), printer->mimeType()); } ResponsePtr RestService::assetIdsRequest(const Printer *printer, - const std::list &ids, bool pretty) + const std::list &ids, bool pretty, + const std::optional &requestId) { using namespace rest_sink; @@ -1205,7 +1211,7 @@ namespace mtconnect { auto message = str.str().substr(0, str.str().size() - 2); return make_unique(status::not_found, - printError(printer, "ASSET_NOT_FOUND", message, pretty), + printError(printer, "ASSET_NOT_FOUND", message, pretty, requestId), printer->mimeType()); } else @@ -1214,7 +1220,7 @@ namespace mtconnect { status::ok, printer->printAssets( m_instanceId, uint32_t(m_sinkContract->getAssetStorage()->getMaxAssets()), - uint32_t(m_sinkContract->getAssetStorage()->getCount()), list, pretty), + uint32_t(m_sinkContract->getAssetStorage()->getCount()), list, pretty, requestId), printer->mimeType()); } } @@ -1400,13 +1406,15 @@ namespace mtconnect { } string RestService::printError(const Printer *printer, const string &errorCode, - const string &text, bool pretty) const + const string &text, bool pretty, + const std::optional &requestId) const { LOG(debug) << "Returning error " << errorCode << ": " << text; if (printer) return printer->printError( m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - m_sinkContract->getCircularBuffer().getSequence(), errorCode, text, pretty); + m_sinkContract->getCircularBuffer().getSequence(), errorCode, text, pretty, + requestId); else return errorCode + ": " + text; } @@ -1482,7 +1490,8 @@ namespace mtconnect { // ------------------------------------------- string RestService::fetchCurrentData(const Printer *printer, const FilterSetOpt &filterSet, - const optional &at, bool pretty) + const optional &at, bool pretty, + const std::optional &requestId) { ObservationList observations; SequenceNumber_t firstSeq, seq; @@ -1506,13 +1515,15 @@ namespace mtconnect { } return printer->printSample(m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - seq, firstSeq, seq - 1, observations, pretty); + seq, firstSeq, seq - 1, observations, pretty, + requestId); } string RestService::fetchSampleData(const Printer *printer, const FilterSetOpt &filterSet, int count, const std::optional &from, const std::optional &to, - SequenceNumber_t &end, bool &endOfBuffer, bool pretty) + SequenceNumber_t &end, bool &endOfBuffer, bool pretty, + const std::optional &requestId) { std::unique_ptr observations; SequenceNumber_t firstSeq, lastSeq; @@ -1542,7 +1553,8 @@ namespace mtconnect { } return printer->printSample(m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - end, firstSeq, lastSeq, *observations, pretty); + end, firstSeq, lastSeq, *observations, pretty, + requestId); } } // namespace sink::rest_sink diff --git a/src/mtconnect/sink/rest_sink/rest_service.hpp b/src/mtconnect/sink/rest_sink/rest_service.hpp index 934231443..5957b401b 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.hpp +++ b/src/mtconnect/sink/rest_sink/rest_service.hpp @@ -101,7 +101,8 @@ namespace mtconnect { ResponsePtr probeRequest(const printer::Printer *p, const std::optional &device = std::nullopt, bool pretty = false, - const std::optional &deviceType = std::nullopt); + const std::optional &deviceType = std::nullopt, + const std::optional &requestId = std::nullopt); /// @brief Handler for a current request /// @param[in] p printer for doc generation @@ -115,7 +116,8 @@ namespace mtconnect { const std::optional &at = std::nullopt, const std::optional &path = std::nullopt, bool pretty = false, - const std::optional &deviceType = std::nullopt); + const std::optional &deviceType = std::nullopt, + const std::optional &requestId = std::nullopt); /// @brief Handler for a sample request /// @param[in] p printer for doc generation @@ -132,7 +134,8 @@ namespace mtconnect { const std::optional &to = std::nullopt, const std::optional &path = std::nullopt, bool pretty = false, - const std::optional &deviceType = std::nullopt); + const std::optional &deviceType = std::nullopt, + const std::optional &requestId = std::nullopt); /// @brief Handler for a streaming sample /// @param[in] session session to stream data to /// @param[in] p printer for doc generation @@ -150,7 +153,7 @@ namespace mtconnect { const std::optional &path = std::nullopt, bool pretty = false, const std::optional &deviceType = std::nullopt, - const std::optional &responseId = std::nullopt); + const std::optional &requestId = std::nullopt); /// @brief Handler for a streaming current /// @param[in] session session to stream data to @@ -164,7 +167,7 @@ namespace mtconnect { const std::optional &path = std::nullopt, bool pretty = false, const std::optional &deviceType = std::nullopt, - const std::optional &responseId = std::nullopt); + const std::optional &requestId = std::nullopt); /// @brief Handler for put/post observation /// @param[in] p printer for response generation /// @param[in] device device @@ -207,7 +210,8 @@ namespace mtconnect { ResponsePtr assetRequest(const printer::Printer *p, const int32_t count, const bool removed, const std::optional &type = std::nullopt, const std::optional &device = std::nullopt, - bool pretty = false); + bool pretty = false, + const std::optional &requestId = std::nullopt); /// @brief Asset request handler using a list of asset ids /// @param[in] p printer for the response document @@ -215,7 +219,8 @@ namespace mtconnect { /// @param[in] pretty `true` to ensure response is formatted /// @return MTConnect Assets response document ResponsePtr assetIdsRequest(const printer::Printer *p, const std::list &ids, - bool pretty = false); + bool pretty = false, + const std::optional &requestId = std::nullopt); /// @brief Asset request handler to update an asset /// @param p printer for the response document @@ -262,7 +267,8 @@ namespace mtconnect { /// @param text descriptive error text /// @return MTConnect Error document std::string printError(const printer::Printer *printer, const std::string &errorCode, - const std::string &text, bool pretty = false) const; + const std::string &text, bool pretty = false, + const std::optional &requestId = std::nullopt) const; /// @name For testing only ///@{ @@ -301,13 +307,15 @@ namespace mtconnect { // Current Data Collection std::string fetchCurrentData(const printer::Printer *printer, const FilterSetOpt &filterSet, - const std::optional &at, bool pretty = false); + const std::optional &at, bool pretty = false, + const std::optional &requestId = std::nullopt); // Sample data collection std::string fetchSampleData(const printer::Printer *printer, const FilterSetOpt &filterSet, int count, const std::optional &from, const std::optional &to, SequenceNumber_t &end, - bool &endOfBuffer, bool pretty = false); + bool &endOfBuffer, bool pretty = false, + const std::optional &requestId = std::nullopt); // Verification methods template From ac8dbebf5aee6053247200f41e184aac3302357e Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 19 Apr 2024 12:37:28 -0400 Subject: [PATCH 025/128] Added format to all the requests --- src/mtconnect/printer/json_printer.cpp | 23 ++- src/mtconnect/printer/json_printer.hpp | 42 ++--- src/mtconnect/printer/printer.hpp | 46 +++-- src/mtconnect/printer/xml_printer.cpp | 18 +- src/mtconnect/printer/xml_printer.hpp | 40 ++--- src/mtconnect/sink/rest_sink/rest_service.cpp | 158 ++++++++++-------- src/mtconnect/sink/rest_sink/rest_service.hpp | 21 ++- .../sink/rest_sink/websocket_session.hpp | 3 +- 8 files changed, 198 insertions(+), 153 deletions(-) diff --git a/src/mtconnect/printer/json_printer.cpp b/src/mtconnect/printer/json_printer.cpp index c604a6536..3aa2ea39b 100644 --- a/src/mtconnect/printer/json_printer.cpp +++ b/src/mtconnect/printer/json_printer.cpp @@ -60,7 +60,8 @@ namespace mtconnect::printer { template inline void header(AutoJsonObject &obj, const string &version, const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, - const string &schemaVersion, const string modelChangeTime, bool validation) + const string &schemaVersion, const string modelChangeTime, bool validation, + const std::optional &requestId) { obj.AddPairs("version", version, "creationTime", getCurrentTime(GMT), "testIndicator", false, "instanceId", instanceId, "sender", hostname, "schemaVersion", schemaVersion); @@ -71,6 +72,8 @@ namespace mtconnect::printer { obj.AddPairs("bufferSize", bufferSize); if (validation) obj.AddPairs("validation", true); + if (requestId) + obj.AddPairs("requestId", *requestId); } template @@ -78,10 +81,11 @@ namespace mtconnect::printer { const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetBufferSize, const unsigned int assetCount, const string &schemaVersion, - const string modelChangeTime, const bool validation) + const string modelChangeTime, const bool validation, + const std::optional &requestId) { header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, - validation); + validation, requestId); obj.AddPairs("assetBufferSize", assetBufferSize, "assetCount", assetCount); } @@ -90,10 +94,11 @@ namespace mtconnect::printer { const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSequence, const uint64_t firstSequence, const uint64_t lastSequence, const string &schemaVersion, - const string modelChangeTime, const bool validation) + const string modelChangeTime, const bool validation, + const std::optional &requestId) { header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, - validation); + validation, requestId); obj.AddPairs("nextSequence", nextSequence, "lastSequence", lastSequence, "firstSequence", firstSequence); } @@ -128,7 +133,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); header(obj, m_version, m_senderName, instanceId, bufferSize, *m_schemaVersion, - m_modelChangeTime, m_validation); + m_modelChangeTime, m_validation, requestId); } { if (m_jsonVersion > 1) @@ -186,7 +191,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); probeAssetHeader(obj, m_version, m_senderName, instanceId, bufferSize, assetBufferSize, - assetCount, *m_schemaVersion, m_modelChangeTime, m_validation); + assetCount, *m_schemaVersion, m_modelChangeTime, m_validation, requestId); } { obj.Key("Devices"); @@ -214,7 +219,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); probeAssetHeader(obj, m_version, m_senderName, instanceId, 0, bufferSize, assetCount, - *m_schemaVersion, m_modelChangeTime, m_validation); + *m_schemaVersion, m_modelChangeTime, m_validation, requestId); } { obj.Key("Assets"); @@ -413,7 +418,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); streamHeader(obj, m_version, m_senderName, instanceId, bufferSize, nextSeq, firstSeq, - lastSeq, *m_schemaVersion, m_modelChangeTime, m_validation); + lastSeq, *m_schemaVersion, m_modelChangeTime, m_validation, requestId); } { diff --git a/src/mtconnect/printer/json_printer.hpp b/src/mtconnect/printer/json_printer.hpp index 102cf51ec..119f77b89 100644 --- a/src/mtconnect/printer/json_printer.hpp +++ b/src/mtconnect/printer/json_printer.hpp @@ -30,27 +30,27 @@ namespace mtconnect::printer { JsonPrinter(uint32_t jsonVersion, bool pretty = false, bool validation = false); ~JsonPrinter() override = default; - std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false, - const std::optional requestId = std::nullopt) const override; - - std::string printProbe(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const unsigned int assetBufferSize, - const unsigned int assetCount, const std::list &devices, - const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false, - const std::optional requestId = std::nullopt) const override; - - std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, - observation::ObservationList &results, - bool pretty = false, - const std::optional requestId = std::nullopt) const override; - std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, - const unsigned int assetCount, const asset::AssetList &asset, - bool pretty = false, - const std::optional requestId = std::nullopt) const override; + std::string printErrors( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const ProtoErrorList &list, bool pretty = false, + const std::optional requestId = std::nullopt) const override; + + std::string printProbe( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const unsigned int assetBufferSize, const unsigned int assetCount, + const std::list &devices, const std::map *count = nullptr, + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const override; + + std::string printSample( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, + bool pretty = false, + const std::optional requestId = std::nullopt) const override; + std::string printAssets( + const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, + const asset::AssetList &asset, bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string mimeType() const override { return "application/mtconnect+json"; } uint32_t getJsonVersion() const { return m_jsonVersion; } diff --git a/src/mtconnect/printer/printer.hpp b/src/mtconnect/printer/printer.hpp index 38727109f..d6526a98b 100644 --- a/src/mtconnect/printer/printer.hpp +++ b/src/mtconnect/printer/printer.hpp @@ -61,10 +61,10 @@ namespace mtconnect { /// @param[in] errorCode an error code /// @param[in] errorText the error text /// @return the error document - virtual std::string printError(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const std::string &errorCode, - const std::string &errorText, bool pretty = false, - const std::optional requestId = std::nullopt) const + virtual std::string printError( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const std::string &errorCode, const std::string &errorText, bool pretty = false, + const std::optional requestId = std::nullopt) const { return printErrors(instanceId, bufferSize, nextSeq, {{errorCode, errorText}}); } @@ -74,10 +74,10 @@ namespace mtconnect { /// @param[in] nextSeq the next sequence /// @param[in] list the list of errors /// @return the MTConnect Error document - virtual std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false, - const std::optional requestId = std::nullopt) const = 0; + virtual std::string printErrors( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const ProtoErrorList &list, bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief Generate an MTConnect Devices document /// @param[in] instanceId the instance id /// @param[in] bufferSize the buffer size @@ -87,13 +87,12 @@ namespace mtconnect { /// @param[in] devices a list of devices /// @param[in] count optional asset count and type association /// @return the MTConnect Devices document - virtual std::string printProbe(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const unsigned int assetBufferSize, - const unsigned int assetCount, - const std::list &devices, - const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false, - const std::optional requestId = std::nullopt) const = 0; + virtual std::string printProbe( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const unsigned int assetBufferSize, const unsigned int assetCount, + const std::list &devices, const std::map *count = nullptr, + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief Print a MTConnect Streams document /// @param[in] instanceId the instance id /// @param[in] bufferSize the buffer size @@ -102,21 +101,20 @@ namespace mtconnect { /// @param[in] lastSeq the last sequnce /// @param[in] results a list of observations /// @return the MTConnect Streams document - virtual std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const uint64_t firstSeq, - const uint64_t lastSeq, observation::ObservationList &results, - bool pretty = false, - const std::optional requestId = std::nullopt) const = 0; + virtual std::string printSample( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, + bool pretty = false, const std::optional requestId = std::nullopt) const = 0; /// @brief Generate an MTConnect Assets document /// @param[in] anInstanceId the instance id /// @param[in] bufferSize the buffer size /// @param[in] assetCount the asset count /// @param[in] asset the list of assets /// @return the MTConnect Assets document - virtual std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, - const unsigned int assetCount, asset::AssetList const &asset, - bool pretty = false, - const std::optional requestId = std::nullopt) const = 0; + virtual std::string printAssets( + const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, + asset::AssetList const &asset, bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief get the mime type for the documents /// @return the mime type virtual std::string mimeType() const = 0; diff --git a/src/mtconnect/printer/xml_printer.cpp b/src/mtconnect/printer/xml_printer.cpp index 2e5badb39..8a6db2f17 100644 --- a/src/mtconnect/printer/xml_printer.cpp +++ b/src/mtconnect/printer/xml_printer.cpp @@ -352,8 +352,8 @@ namespace mtconnect::printer { { XmlWriter writer(m_pretty || pretty); - initXmlDoc(writer, eERROR, instanceId, bufferSize, 0, 0, nextSeq, 0, nextSeq - 1, - nullptr, requestId); + initXmlDoc(writer, eERROR, instanceId, bufferSize, 0, 0, nextSeq, 0, nextSeq - 1, nullptr, + requestId); { AutoElement e1(writer, "Errors"); @@ -419,8 +419,8 @@ namespace mtconnect::printer { string XmlPrinter::printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, - const uint64_t lastSeq, ObservationList &observations, - bool pretty, const std::optional requestId) const + const uint64_t lastSeq, ObservationList &observations, bool pretty, + const std::optional requestId) const { string ret; @@ -500,16 +500,15 @@ namespace mtconnect::printer { } string XmlPrinter::printAssets(const uint64_t instanceId, const unsigned int bufferSize, - const unsigned int assetCount, const AssetList &asset, - bool pretty, + const unsigned int assetCount, const AssetList &asset, bool pretty, const std::optional requestId) const { string ret; try { XmlWriter writer(m_pretty || pretty); - initXmlDoc(writer, eASSETS, instanceId, 0u, bufferSize, assetCount, 0ull, - 0, 0, nullptr, requestId); + initXmlDoc(writer, eASSETS, instanceId, 0u, bufferSize, assetCount, 0ull, 0, 0, nullptr, + requestId); { AutoElement ele(writer, "Assets"); @@ -652,11 +651,10 @@ namespace mtconnect::printer { sprintf(version, "%d.%d.%d.%d", AGENT_VERSION_MAJOR, AGENT_VERSION_MINOR, AGENT_VERSION_PATCH, AGENT_VERSION_BUILD); addAttribute(writer, "version", version); - + if (requestId) addAttribute(writer, "requestId", *requestId); - int major, minor; char c; stringstream v(*m_schemaVersion); diff --git a/src/mtconnect/printer/xml_printer.hpp b/src/mtconnect/printer/xml_printer.hpp index 337f1fae8..d5eba57d6 100644 --- a/src/mtconnect/printer/xml_printer.hpp +++ b/src/mtconnect/printer/xml_printer.hpp @@ -43,25 +43,27 @@ namespace mtconnect { XmlPrinter(bool pretty = false, bool validation = false); ~XmlPrinter() override = default; - std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false, - const std::optional requestId = std::nullopt) const override; - - std::string printProbe(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const unsigned int assetBufferSize, - const unsigned int assetCount, const std::list &devices, - const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false, - const std::optional requestId = std::nullopt) const override; - - std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const uint64_t firstSeq, - const uint64_t lastSeq, observation::ObservationList &results, - bool pretty = false, const std::optional requestId = std::nullopt) const override; - std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, - const unsigned int assetCount, const asset::AssetList &asset, - bool pretty = false, const std::optional requestId = std::nullopt) const override; + std::string printErrors( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const ProtoErrorList &list, bool pretty = false, + const std::optional requestId = std::nullopt) const override; + + std::string printProbe( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const unsigned int assetBufferSize, const unsigned int assetCount, + const std::list &devices, const std::map *count = nullptr, + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const override; + + std::string printSample( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, + bool pretty = false, + const std::optional requestId = std::nullopt) const override; + std::string printAssets( + const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, + const asset::AssetList &asset, bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string mimeType() const override { return "text/xml"; } /// @brief Add a Devices XML device namespace diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index fb9951d5d..b9e150232 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -113,6 +113,7 @@ namespace mtconnect { {"from", QUERY, "Sequence number at to start reporting observations"}, {"interval", QUERY, "Time in ms between publishing data–starts streaming"}, {"pretty", QUERY, "Instructs the result to be pretty printed"}, + {"format", QUERY, "The format of the response document: 'xml' or 'json'"}, {"heartbeat", QUERY, "Time in ms between publishing a empty document when no data has changed"}}); @@ -475,8 +476,8 @@ namespace mtconnect { auto device = request->parameter("device"); auto pretty = *request->parameter("pretty"); auto deviceType = request->parameter("deviceType"); - - auto printer = printerForAccepts(request->m_accepts); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); if (device && !ends_with(request->m_path, string("probe")) && m_sinkContract->findDeviceByUUIDorName(*device) == nullptr) @@ -487,19 +488,21 @@ namespace mtconnect { return false; } - respond(session, probeRequest(printer, device, pretty, deviceType), request->m_requestId); + respond(session, probeRequest(printer, device, pretty, deviceType, request->m_requestId), + request->m_requestId); return true; }; m_server ->addRouting({boost::beast::http::verb::get, - "/probe?pretty={bool:false}&deviceType={string}", handler}) + "/probe?pretty={bool:false}&deviceType={string}&format={string}", handler}) .document("MTConnect probe request", "Provides metadata service for the MTConnect Devices information model for all " "devices."); m_server ->addRouting({boost::beast::http::verb::get, - "/{device}/probe?pretty={bool:false}&deviceType={string}", handler}) + "/{device}/probe?pretty={bool:false}&deviceType={string}&format={string}", + handler}) .document("MTConnect probe request", "Provides metadata service for the MTConnect Devices information model for " "device identified by `device` matching `name` or `uuid`.") @@ -507,14 +510,15 @@ namespace mtconnect { // Must be last m_server - ->addRouting( - {boost::beast::http::verb::get, "/?pretty={bool:false}&deviceType={string}", handler}) + ->addRouting({boost::beast::http::verb::get, + "/?pretty={bool:false}&deviceType={string}&format={string}", handler}) .document("MTConnect probe request", "Provides metadata service for the MTConnect Devices information model for all " "devices."); m_server ->addRouting({boost::beast::http::verb::get, - "/{device}?pretty={bool:false}&deviceType={string}", handler}) + "/{device}?pretty={bool:false}&deviceType={string}&format={string}", + handler}) .document("MTConnect probe request", "Provides metadata service for the MTConnect Devices information model for " "device identified by `device` matching `name` or `uuid`."); @@ -526,11 +530,13 @@ namespace mtconnect { auto handler = [&](SessionPtr session, RequestPtr request) -> bool { auto removed = *request->parameter("removed"); auto count = *request->parameter("count"); - auto printer = printerForAccepts(request->m_accepts); + auto pretty = *request->parameter("pretty"); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); respond(session, assetRequest(printer, count, removed, request->parameter("type"), - request->parameter("device")), + request->parameter("device"), pretty, request->m_requestId), request->m_requestId); return true; }; @@ -539,6 +545,7 @@ namespace mtconnect { auto asset = request->parameter("assetIds"); if (asset) { + auto pretty = *request->parameter("pretty"); auto printer = m_sinkContract->getPrinter(acceptFormat(request->m_accepts)); list ids; @@ -546,11 +553,13 @@ namespace mtconnect { string id; while (getline(str, id, ';')) ids.emplace_back(id); - respond(session, assetIdsRequest(printer, ids), request->m_requestId); + respond(session, assetIdsRequest(printer, ids, pretty, request->m_requestId), + request->m_requestId); } else { - auto printer = printerForAccepts(request->m_accepts); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); auto error = printError(printer, "INVALID_REQUEST", "No asset given"); respond(session, make_unique(rest_sink::status::bad_request, error, printer->mimeType()), @@ -561,7 +570,7 @@ namespace mtconnect { string qp( "type={string}&removed={bool:false}&" - "count={integer:100}&device={string}&pretty={bool:false}"); + "count={integer:100}&device={string}&pretty={bool:false}&format={string}"); m_server->addRouting({boost::beast::http::verb::get, "/assets?" + qp, handler}) .document("MTConnect assets request", "Returns up to `count` assets"); m_server->addRouting({boost::beast::http::verb::get, "/asset?" + qp, handler}) @@ -582,7 +591,8 @@ namespace mtconnect { if (m_server->arePutsAllowed()) { auto putHandler = [&](SessionPtr session, RequestPtr request) -> bool { - auto printer = printerForAccepts(request->m_accepts); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); respond(session, putAssetRequest(printer, request->m_body, request->parameter("type"), request->parameter("device"), @@ -598,7 +608,8 @@ namespace mtconnect { list ids; stringstream str(*asset); string id; - auto printer = printerForAccepts(request->m_accepts); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); while (getline(str, id, ';')) ids.emplace_back(id); @@ -606,9 +617,11 @@ namespace mtconnect { } else { + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + respond(session, - deleteAllAssetsRequest(printerForAccepts(request->m_accepts), - request->parameter("device"), + deleteAllAssetsRequest(printer, request->parameter("device"), request->parameter("type")), request->m_requestId); } @@ -622,34 +635,42 @@ namespace mtconnect { { m_server ->addRouting( - {t, "/" + asset + "/{assetId}?device={string}&type={string}", putHandler}) + {t, "/" + asset + "/{assetId}?device={string}&type={string}&format={string}", + putHandler}) .document("Upload an asset by identified by `assetId`", "Updates or adds an asset with the asset XML in the body"); - m_server->addRouting({t, "/" + asset + "?device={string}&type={string}", putHandler}) + m_server + ->addRouting( + {t, "/" + asset + "?device={string}&type={string}&format={string}", putHandler}) .document("Upload an asset by identified by `assetId`", "Updates or adds an asset with the asset XML in the body"); - m_server->addRouting({t, "/{device}/" + asset + "/{assetId}?type={string}", putHandler}) + m_server + ->addRouting({t, "/{device}/" + asset + "/{assetId}?type={string}&format={string}", + putHandler}) .document("Upload an asset by identified by `assetId`", "Updates or adds an asset with the asset XML in the body"); - m_server->addRouting({t, "/{device}/" + asset + "?type={string}", putHandler}) + m_server + ->addRouting( + {t, "/{device}/" + asset + "?type={string}&format={string}", putHandler}) .document("Upload an asset by identified by `assetId`", "Updates or adds an asset with the asset XML in the body"); } m_server ->addRouting({boost::beast::http::verb::delete_, - "/" + asset + "?device={string}&type={string}", deleteHandler}) + "/" + asset + "?device={string}&type={string}&format={string}", + deleteHandler}) .document("Delete all assets for a device and type", "Device and type are optional. If they are not given, it assumes there is " "no constraint"); m_server - ->addRouting( - {boost::beast::http::verb::delete_, "/" + asset + "/{assetId}", deleteHandler}) + ->addRouting({boost::beast::http::verb::delete_, + "/" + asset + "/{assetId}?format={string}", deleteHandler}) .document("Delete asset identified by `assetId`", "Marks the asset as removed and creates an AssetRemoved event"); m_server ->addRouting({boost::beast::http::verb::delete_, - "/{device}/" + asset + "?type={string}", deleteHandler}) + "/{device}/" + asset + "?type={string}&format={string}", deleteHandler}) .document("Delete all assets for a device and type", "Device and type are optional. If they are not given, it assumes there is " "no constraint") @@ -666,20 +687,25 @@ namespace mtconnect { auto interval = request->parameter("interval"); if (interval) { - streamCurrentRequest(session, printerForAccepts(request->m_accepts), *interval, - request->parameter("device"), + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + + streamCurrentRequest(session, printer, *interval, request->parameter("device"), request->parameter("path"), *request->parameter("pretty"), request->parameter("deviceType"), request->m_requestId); } else { + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + respond( session, - currentRequest( - printerForAccepts(request->m_accepts), request->parameter("device"), - request->parameter("at"), request->parameter("path"), - *request->parameter("pretty"), request->parameter("deviceType")), + currentRequest(printer, request->parameter("device"), + request->parameter("at"), request->parameter("path"), + *request->parameter("pretty"), + request->parameter("deviceType"), request->m_requestId), request->m_requestId); } return true; @@ -688,7 +714,7 @@ namespace mtconnect { string qp( "path={string}&at={unsigned_integer}&" "interval={integer}&pretty={bool:false}&" - "deviceType={string}"); + "deviceType={string}&format={string}"); m_server->addRouting({boost::beast::http::verb::get, "/current?" + qp, handler}) .document("MTConnect current request", "Gets a stapshot of the state of all the observations for all devices " @@ -707,23 +733,29 @@ namespace mtconnect { auto interval = request->parameter("interval"); if (interval) { + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + streamSampleRequest( - session, printerForAccepts(request->m_accepts), *interval, - *request->parameter("heartbeat"), *request->parameter("count"), - request->parameter("device"), request->parameter("from"), - request->parameter("path"), *request->parameter("pretty"), - request->parameter("deviceType"), request->m_requestId); + session, printer, *interval, *request->parameter("heartbeat"), + *request->parameter("count"), request->parameter("device"), + request->parameter("from"), request->parameter("path"), + *request->parameter("pretty"), request->parameter("deviceType"), + request->m_requestId); } else { - respond( - session, - sampleRequest( - printerForAccepts(request->m_accepts), *request->parameter("count"), - request->parameter("device"), request->parameter("from"), - request->parameter("to"), request->parameter("path"), - *request->parameter("pretty"), request->parameter("deviceType")), - request->m_requestId); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + + respond(session, + sampleRequest( + printer, *request->parameter("count"), + request->parameter("device"), request->parameter("from"), + request->parameter("to"), request->parameter("path"), + *request->parameter("pretty"), request->parameter("deviceType"), + request->m_requestId), + request->m_requestId); } return true; }; @@ -733,7 +765,7 @@ namespace mtconnect { "interval={integer}&count={integer:100}&" "heartbeat={integer:10000}&to={unsigned_integer}&" "pretty={bool:false}&" - "deviceType={string}"); + "deviceType={string}&format={string}"); m_server->addRouting({boost::beast::http::verb::get, "/sample?" + qp, handler}) .document("MTConnect sample request", "Gets a time series of at maximum `count` observations for all devices " @@ -761,11 +793,11 @@ namespace mtconnect { if (ts) queries.erase("time"); auto device = request->parameter("device"); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); - respond( - session, - putObservationRequest(printerForAccepts(request->m_accepts), *device, queries, ts), - request->m_requestId); + respond(session, putObservationRequest(printer, *device, queries, ts), + request->m_requestId); return true; } else @@ -825,7 +857,7 @@ namespace mtconnect { m_sinkContract->getCircularBuffer().getSequence(), uint32_t(m_sinkContract->getAssetStorage()->getMaxAssets()), uint32_t(m_sinkContract->getAssetStorage()->getCount()), deviceList, - &counts, false, pretty), + &counts, false, pretty, requestId), printer->mimeType()); } @@ -851,7 +883,7 @@ namespace mtconnect { // Check if there is a frequency to stream data or not return make_unique(rest_sink::status::ok, - fetchCurrentData(printer, filter, at, pretty), + fetchCurrentData(printer, filter, at, pretty, requestId), printer->mimeType()); } @@ -882,7 +914,7 @@ namespace mtconnect { return make_unique( rest_sink::status::ok, - fetchSampleData(printer, filter, count, from, to, end, endOfBuffer, pretty), + fetchSampleData(printer, filter, count, from, to, end, endOfBuffer, pretty, requestId), printer->mimeType()); } @@ -1210,9 +1242,9 @@ namespace mtconnect { str << id << ", "; auto message = str.str().substr(0, str.str().size() - 2); - return make_unique(status::not_found, - printError(printer, "ASSET_NOT_FOUND", message, pretty, requestId), - printer->mimeType()); + return make_unique( + status::not_found, printError(printer, "ASSET_NOT_FOUND", message, pretty, requestId), + printer->mimeType()); } else { @@ -1400,11 +1432,6 @@ namespace mtconnect { return "xml"; } - const Printer *RestService::printerForAccepts(const std::string &accepts) const - { - return m_sinkContract->getPrinter(acceptFormat(accepts)); - } - string RestService::printError(const Printer *printer, const string &errorCode, const string &text, bool pretty, const std::optional &requestId) const @@ -1413,8 +1440,7 @@ namespace mtconnect { if (printer) return printer->printError( m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - m_sinkContract->getCircularBuffer().getSequence(), errorCode, text, pretty, - requestId); + m_sinkContract->getCircularBuffer().getSequence(), errorCode, text, pretty, requestId); else return errorCode + ": " + text; } @@ -1515,8 +1541,7 @@ namespace mtconnect { } return printer->printSample(m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - seq, firstSeq, seq - 1, observations, pretty, - requestId); + seq, firstSeq, seq - 1, observations, pretty, requestId); } string RestService::fetchSampleData(const Printer *printer, const FilterSetOpt &filterSet, @@ -1553,8 +1578,7 @@ namespace mtconnect { } return printer->printSample(m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - end, firstSeq, lastSeq, *observations, pretty, - requestId); + end, firstSeq, lastSeq, *observations, pretty, requestId); } } // namespace sink::rest_sink diff --git a/src/mtconnect/sink/rest_sink/rest_service.hpp b/src/mtconnect/sink/rest_sink/rest_service.hpp index 5957b401b..f58c7df28 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.hpp +++ b/src/mtconnect/sink/rest_sink/rest_service.hpp @@ -259,7 +259,26 @@ namespace mtconnect { /// @brief get a printer given a list of formats from the Accepts header /// @param accepts the accepts header /// @return pointer to a printer - const printer::Printer *printerForAccepts(const std::string &accepts) const; + const printer::Printer *printerForAccepts(const std::string &accepts) const + { + return m_sinkContract->getPrinter(acceptFormat(accepts)); + } + + /// @brief get a printer for a format or using the accepts header. Falls back to header accept + /// if format incorrect. + /// @param accepts the accept header of the request + /// @param format optional format query param + /// @return pointer to a printer + const printer::Printer *getPrinter(const std::string &accepts, + std::optional format) const + { + const printer::Printer *printer = nullptr; + if (format) + printer = m_sinkContract->getPrinter(*format); + if (printer == nullptr) + printer = printerForAccepts(accepts); + return printer; + } /// @brief Generate an MTConnect Error document /// @param printer printer to generate error diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index fcf91939e..e8677ebdb 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -421,14 +421,13 @@ namespace mtconnect::sink::rest_sink { m_request.reset(); closeStream(); } - + void closeStream() override { if (m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } - auto getExecutor() { return m_stream.get_executor(); } auto &stream() { return m_stream; } From 64fa6a2a16171b58fbd91d78a431d8d02e010bbb Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 17:03:48 -0400 Subject: [PATCH 026/128] Fixed session leak with observer circular ref in handler. --- src/mtconnect/observation/change_observer.hpp | 15 ++++ .../sink/mqtt_sink/mqtt2_service.cpp | 5 ++ src/mtconnect/sink/rest_sink/rest_service.cpp | 9 +++ src/mtconnect/sink/rest_sink/session.hpp | 8 ++ .../sink/rest_sink/websocket_session.hpp | 75 +++++++++++++------ 5 files changed, 91 insertions(+), 21 deletions(-) diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index 3f4e5c2eb..439439156 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -142,6 +142,14 @@ namespace mtconnect::observation { /// @brief try to lock the mutex auto try_lock() { return m_mutex.try_lock(); } ///@} + + /// @brief clear the observer information. + void clear() + { + std::unique_lock lock(m_mutex); + m_signalers.clear(); + m_handler.clear(); + } private: boost::asio::io_context::strand &m_strand; @@ -237,6 +245,13 @@ namespace mtconnect::observation { /// @brief method to determine if the sink is running virtual bool isRunning() = 0; + + /// @brief Stop all timers and release resources. + virtual bool cancel() + { + m_observer.clear(); + return true; + } /// @brief handler callback when an action needs to be taken /// diff --git a/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp index 0a859fa84..fa9770715 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp @@ -163,6 +163,11 @@ namespace mtconnect { auto client = m_client.lock(); return client && client->isRunning() && client->isConnected(); } + + bool cancel() override + { + return true; + } DevicePtr m_device; std::weak_ptr m_client; diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index b9e150232..389e34cea 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -934,6 +934,7 @@ namespace mtconnect { if (sink && isRunning()) { m_session->fail(status, message); + cancel(); } else { @@ -959,6 +960,13 @@ namespace mtconnect { return server->isRunning(); } } + + bool cancel() override + { + observation::AsyncObserver::cancel(); + m_session.reset(); + return true; + } std::weak_ptr m_sink; //! weak shared pointer to the sink. handles shutdown timer race @@ -1012,6 +1020,7 @@ namespace mtconnect { asyncResponse->m_sink = getptr(); asyncResponse->m_pretty = pretty; asyncResponse->m_requestId = requestId; + session->addObserver(asyncResponse); if (m_logStreamData) { diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index 4e2bc52ab..8d3f76412 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -25,6 +25,7 @@ #include #include "mtconnect/config.hpp" +#include "mtconnect/observation/change_observer.hpp" #include "routing.hpp" namespace mtconnect::sink::rest_sink { @@ -117,6 +118,12 @@ namespace mtconnect::sink::rest_sink { m_message = msg; m_unauthorized = true; } + + /// @brief Add an observer to the list for cleanup later. + void addObserver(std::weak_ptr observer) + { + m_observers.push_back(observer); + } protected: Dispatch m_dispatch; @@ -127,6 +134,7 @@ namespace mtconnect::sink::rest_sink { bool m_allowPuts {false}; std::set m_allowPutsFrom; boost::asio::ip::tcp::endpoint m_remote; + std::list> m_observers; }; } // namespace mtconnect::sink::rest_sink diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index e8677ebdb..e38b0c4dd 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -96,6 +96,29 @@ namespace mtconnect::sink::rest_sink { beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr()))); } + + void close() override + { + NAMED_SCOPE("PlainWebsocketSession::close"); + if (!m_isOpen) + return; + + auto ptr = derived().shared_ptr(); + + m_request.reset(); + m_requests.clear(); + for (auto obs : m_observers) + { + auto optr = obs.lock(); + if (optr) + { + optr->cancel(); + } + } + closeStream(); + + m_isOpen = false; + } void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { @@ -128,7 +151,9 @@ namespace mtconnect::sink::rest_sink { req.m_streaming = true; if (complete) + { complete(); + } } else { @@ -145,6 +170,12 @@ namespace mtconnect::sink::rest_sink { std::optional requestId = std::nullopt) override { NAMED_SCOPE("WebsocketSession::writeChunk"); + + if (!derived().stream().is_open()) + { + return; + } + if (requestId) { LOG(trace) << "Waiting for mutex"; @@ -173,6 +204,8 @@ namespace mtconnect::sink::rest_sink { fail(status::internal_server_error, "Error occurred in accpet", ec); return; } + + m_isOpen = true; derived().stream().async_read( m_buffer, beast::bind_front_handler(&WebsocketSession::onRead, derived().shared_ptr())); @@ -188,7 +221,7 @@ namespace mtconnect::sink::rest_sink { if (it != m_requests.end()) { auto &req = it->second; - req.m_complete = complete; + req.m_complete = std::move(complete); req.m_streamBuffer.emplace(); std::ostream str(&req.m_streamBuffer.value()); @@ -236,6 +269,7 @@ namespace mtconnect::sink::rest_sink { if (req.m_complete) { boost::asio::post(derived().stream().get_executor(), req.m_complete); + req.m_complete = nullptr; } if (!req.m_streaming) @@ -277,6 +311,12 @@ namespace mtconnect::sink::rest_sink { using namespace rapidjson; using namespace std; + + if (len == 0) + { + LOG(trace) << "Empty message received"; + return; + } // Parse the buffer as a JSON request with parameters matching // REST API @@ -395,6 +435,7 @@ namespace mtconnect::sink::rest_sink { std::mutex m_mutex; std::atomic_bool m_busy; std::deque m_messageQueue; + bool m_isOpen { false }; }; template @@ -412,19 +453,15 @@ namespace mtconnect::sink::rest_sink { { beast::get_lowest_layer(m_stream).expires_never(); } - ~PlainWebsocketSession() { close(); } - - void close() override - { - NAMED_SCOPE("PlainWebsocketSession::close"); - - m_request.reset(); - closeStream(); + ~PlainWebsocketSession() + { + if (m_isOpen) + close(); } void closeStream() override { - if (m_stream.is_open()) + if (m_isOpen && m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } @@ -455,23 +492,19 @@ namespace mtconnect::sink::rest_sink { { beast::get_lowest_layer(m_stream).expires_never(); } - ~TlsWebsocketSession() { close(); } - + ~TlsWebsocketSession() + { + if (m_isOpen) + close(); + } + auto &stream() { return m_stream; } auto getExecutor() { return m_stream.get_executor(); } - void close() override - { - NAMED_SCOPE("TlsWebsocketSession::close"); - - m_request.reset(); - closeStream(); - } - void closeStream() override { - if (m_stream.is_open()) + if (m_isOpen && m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } From 3bd86f491b8112b2839c78dd7aa7b3f7c9f0fae8 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 17:07:11 -0400 Subject: [PATCH 027/128] Added code to session impl as well. --- src/mtconnect/sink/rest_sink/session_impl.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index 40777da00..f1eeef2e5 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -527,6 +527,18 @@ namespace mtconnect::sink::rest_sink { if (!m_closing) { m_closing = true; + + // Release all references from observers. + for (auto obs : m_observers) + { + auto optr = obs.lock(); + if (optr) + { + optr->cancel(); + } + } + + // Set the timeout. beast::get_lowest_layer(m_stream).expires_after(std::chrono::seconds(30)); From 6201b2c63e70545832b87b4d5fb7992388054318 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 17:11:05 -0400 Subject: [PATCH 028/128] Fixed test issues --- test_package/agent_test_helper.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test_package/agent_test_helper.hpp b/test_package/agent_test_helper.hpp index 13c14fc94..a0f93a0bb 100644 --- a/test_package/agent_test_helper.hpp +++ b/test_package/agent_test_helper.hpp @@ -78,13 +78,15 @@ namespace mtconnect { writeResponse(std::move(response), complete); } } - void beginStreaming(const std::string &mimeType, Complete complete) override + void beginStreaming(const std::string &mimeType, Complete complete, + std::optional requestId = std::nullopt) override { m_mimeType = mimeType; m_streaming = true; complete(); } - void writeChunk(const std::string &chunk, Complete complete) override + void writeChunk(const std::string &chunk, Complete complete, + std::optional requestId = std::nullopt) override { m_chunkBody = chunk; if (m_streaming) From bbad3dc2363f14fb27f5112fb7f4713777c646ff Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 17:33:08 -0400 Subject: [PATCH 029/128] fixed bug in dispatch --- src/mtconnect/sink/rest_sink/routing.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index 230534222..0710f15b1 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -187,6 +187,10 @@ namespace mtconnect::sink::rest_sink { } } } + else + { + return false; + } } for (auto &p : m_queryParameters) From a89c4c78df0e8efa644917c89ec5d72530bf36a4 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 21:31:27 -0400 Subject: [PATCH 030/128] refactored mqtt sinks and tests. Added cancel to websockets --- agent_lib/CMakeLists.txt | 8 +- src/mtconnect/configuration/agent_config.cpp | 4 +- src/mtconnect/observation/change_observer.hpp | 16 +- .../sink/mqtt_sink/mqtt2_service.cpp | 357 ---------- .../sink/mqtt_sink/mqtt2_service.hpp | 205 ------ .../sink/mqtt_sink/mqtt_legacy_service.cpp | 197 ++++++ .../sink/mqtt_sink/mqtt_legacy_service.hpp | 107 +++ src/mtconnect/sink/mqtt_sink/mqtt_service.cpp | 297 +++++++-- src/mtconnect/sink/mqtt_sink/mqtt_service.hpp | 108 ++- src/mtconnect/sink/rest_sink/rest_service.cpp | 22 +- src/mtconnect/sink/rest_sink/session.hpp | 16 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 3 +- .../sink/rest_sink/websocket_session.hpp | 26 +- test_package/CMakeLists.txt | 2 +- test_package/agent_test_helper.hpp | 40 +- test_package/mqtt_isolated_test.cpp | 2 +- test_package/mqtt_legacy_sink_test.cpp | 630 ++++++++++++++++++ test_package/mqtt_sink_2_test.cpp | 426 ------------ test_package/mqtt_sink_test.cpp | 408 +++--------- 19 files changed, 1451 insertions(+), 1423 deletions(-) delete mode 100644 src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp delete mode 100644 src/mtconnect/sink/mqtt_sink/mqtt2_service.hpp create mode 100644 src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp create mode 100644 src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp create mode 100644 test_package/mqtt_legacy_sink_test.cpp delete mode 100644 test_package/mqtt_sink_2_test.cpp diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index 26afac8c5..c39284674 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -246,13 +246,13 @@ set(AGENT_SOURCES # src/sink/mqtt_sink HEADER_FILE_ONLY - "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.hpp" - "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.hpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.hpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.hpp" #src/sink/mqtt_sink SOURCE_FILES_ONLY - "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" - "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.cpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.cpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" # src/sink/rest_sink HEADER_FILE_ONLY diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index bd1349306..d372df52a 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -58,7 +58,7 @@ #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/device_model/device.hpp" #include "mtconnect/printer/xml_printer.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt2_service.hpp" +#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" #include "mtconnect/sink/mqtt_sink/mqtt_service.hpp" #include "mtconnect/sink/rest_sink/rest_service.hpp" #include "mtconnect/source/adapter/agent_adapter/agent_adapter.hpp" @@ -112,8 +112,8 @@ namespace mtconnect::configuration { bool success = false; + sink::mqtt_sink::MqttLegacyService::registerFactory(m_sinkFactory); sink::mqtt_sink::MqttService::registerFactory(m_sinkFactory); - sink::mqtt_sink::Mqtt2Service::registerFactory(m_sinkFactory); sink::rest_sink::RestService::registerFactory(m_sinkFactory); adapter::shdr::ShdrAdapter::registerFactory(m_sourceFactory); adapter::mqtt_adapter::MqttAdapter::registerFactory(m_sourceFactory); diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index 439439156..b38cc6161 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -142,13 +142,14 @@ namespace mtconnect::observation { /// @brief try to lock the mutex auto try_lock() { return m_mutex.try_lock(); } ///@} - + /// @brief clear the observer information. void clear() { std::unique_lock lock(m_mutex); - m_signalers.clear(); + m_signalers.clear(); m_handler.clear(); + m_timer.cancel(); } private: @@ -245,7 +246,7 @@ namespace mtconnect::observation { /// @brief method to determine if the sink is running virtual bool isRunning() = 0; - + /// @brief Stop all timers and release resources. virtual bool cancel() { @@ -265,9 +266,15 @@ namespace mtconnect::observation { auto getSequence() const { return m_sequence; } auto isEndOfBuffer() const { return m_endOfBuffer; } const auto &getFilter() const { return m_filter; } + const auto &getRequestId() const { return m_requestId; } + ///@} + ///@{ + /// @name setters + + /// @brief sets the optonal request id for webservices. + void setRequestId(const std::optional &id) { m_requestId = id; } ///@} - /// mutable bool m_endOfBuffer {false}; //! Public indicator that we are at the end of the buffer @@ -291,5 +298,6 @@ namespace mtconnect::observation { ChangeObserver m_observer; //! the change observer mtconnect::buffer::CircularBuffer &m_buffer; //! reference to the circular buffer + std::optional m_requestId; //! request id }; } // namespace mtconnect::observation diff --git a/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp deleted file mode 100644 index fa9770715..000000000 --- a/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp +++ /dev/null @@ -1,357 +0,0 @@ -// -// Copyright Copyright 2009-2023, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#include "mqtt2_service.hpp" - -#include - -#include "mtconnect/configuration/config_options.hpp" -#include "mtconnect/entity/entity.hpp" -#include "mtconnect/entity/factory.hpp" -#include "mtconnect/entity/json_parser.hpp" -#include "mtconnect/mqtt/mqtt_client_impl.hpp" -#include "mtconnect/printer/json_printer.hpp" - -using ptree = boost::property_tree::ptree; -using json = nlohmann::json; - -using namespace std; -using namespace mtconnect; -using namespace mtconnect::asset; - -namespace asio = boost::asio; -namespace config = ::mtconnect::configuration; - -namespace mtconnect { - namespace sink { - namespace mqtt_sink { - // get obeservation in - // create a json printer - // call print - - Mqtt2Service::Mqtt2Service(boost::asio::io_context &context, sink::SinkContractPtr &&contract, - const ConfigOptions &options, const ptree &config) - : Sink("Mqtt2Service", std::move(contract)), - m_context(context), - m_strand(context), - m_options(options), - m_currentTimer(context) - { - // Unique id number for agent instance - m_instanceId = getCurrentTimeInSec(); - - auto jsonPrinter = dynamic_cast(m_sinkContract->getPrinter("json")); - - m_jsonPrinter = make_unique(jsonPrinter->getJsonVersion()); - - m_printer = std::make_unique(jsonPrinter->getJsonVersion()); - - GetOptions(config, m_options, options); - AddOptions(config, m_options, - {{configuration::ProbeTopic, string()}, - {configuration::MqttCaCert, string()}, - {configuration::MqttPrivateKey, string()}, - {configuration::MqttCert, string()}, - {configuration::MqttClientId, string()}, - {configuration::MqttUserName, string()}, - {configuration::MqttPassword, string()}}); - AddDefaultedOptions( - config, m_options, - {{configuration::MqttHost, "127.0.0.1"s}, - {configuration::DeviceTopic, "MTConnect/Probe/[device]"s}, - {configuration::AssetTopic, "MTConnect/Asset/[device]"s}, - {configuration::MqttLastWillTopic, "MTConnect/Probe/[device]/Availability"s}, - {configuration::CurrentTopic, "MTConnect/Current/[device]"s}, - {configuration::SampleTopic, "MTConnect/Sample/[device]"s}, - {configuration::MqttCurrentInterval, 10000ms}, - {configuration::MqttSampleInterval, 500ms}, - {configuration::MqttSampleCount, 1000}, - {configuration::MqttPort, 1883}, - {configuration::MqttTls, false}}); - - int maxTopicDepth {GetOption(options, configuration::MqttMaxTopicDepth).value_or(7)}; - - m_deviceTopic = GetOption(m_options, configuration::ProbeTopic) - .value_or(get(m_options[configuration::DeviceTopic])); - m_assetTopic = getTopic(configuration::AssetTopic, maxTopicDepth); - m_currentTopic = getTopic(configuration::CurrentTopic, maxTopicDepth); - m_sampleTopic = getTopic(configuration::SampleTopic, maxTopicDepth); - - m_currentInterval = *GetOption(m_options, configuration::MqttCurrentInterval); - m_sampleInterval = *GetOption(m_options, configuration::MqttSampleInterval); - - m_sampleCount = *GetOption(m_options, configuration::MqttSampleCount); - } - - void Mqtt2Service::start() - { - if (!m_client) - { - auto clientHandler = make_unique(); - clientHandler->m_connected = [this](shared_ptr client) { - // Publish latest devices, assets, and observations - auto &circ = m_sinkContract->getCircularBuffer(); - std::lock_guard lock(circ); - client->connectComplete(); - - client->publish(m_lastWillTopic, "AVAILABLE"); - pubishInitialContent(); - }; - - auto agentDevice = m_sinkContract->getDeviceByName("Agent"); - auto lwtTopic = get(m_options[configuration::MqttLastWillTopic]); - m_lastWillTopic = formatTopic(lwtTopic, agentDevice, "Agent"); - - if (IsOptionSet(m_options, configuration::MqttTls)) - { - m_client = make_shared(m_context, m_options, std::move(clientHandler), - m_lastWillTopic, "UNAVAILABLE"s); - } - else - { - m_client = make_shared(m_context, m_options, std::move(clientHandler), - m_lastWillTopic, "UNAVAILABLE"s); - } - } - m_client->start(); - } - - void Mqtt2Service::stop() - { - // stop client side - if (m_client) - m_client->stop(); - - m_currentTimer.cancel(); - } - - struct AsyncSample : public observation::AsyncObserver - { - AsyncSample(boost::asio::io_context::strand &strand, - mtconnect::buffer::CircularBuffer &buffer, FilterSet &&filter, - std::chrono::milliseconds interval, std::chrono::milliseconds heartbeat, - std::shared_ptr client, DevicePtr device) - : observation::AsyncObserver(strand, buffer, std::move(filter), interval, heartbeat), - m_device(device), - m_client(client) - {} - - void fail(boost::beast::http::status status, const std::string &message) override - { - LOG(error) << "MQTT Sample Failed: " << message; - } - - bool isRunning() override - { - if (m_sink.expired()) - return false; - - auto client = m_client.lock(); - return client && client->isRunning() && client->isConnected(); - } - - bool cancel() override - { - return true; - } - - DevicePtr m_device; - std::weak_ptr m_client; - std::weak_ptr - m_sink; //! weak shared pointer to the sink. handles shutdown timer race - }; - - void Mqtt2Service::pubishInitialContent() - { - using std::placeholders::_1; - for (auto &dev : m_sinkContract->getDevices()) - { - publish(dev); - - AssetList list; - m_sinkContract->getAssetStorage()->getAssets(list, 100000, true, *(dev->getUuid())); - for (auto &asset : list) - { - publish(asset); - } - } - - auto seq = m_sinkContract->getCircularBuffer().getSequence(); - for (auto &dev : m_sinkContract->getDevices()) - { - FilterSet filterSet = filterForDevice(dev); - auto sampler = - make_shared(m_strand, m_sinkContract->getCircularBuffer(), - std::move(filterSet), m_sampleInterval, 600s, m_client, dev); - sampler->m_sink = getptr(); - sampler->m_handler = boost::bind(&Mqtt2Service::publishSample, this, _1); - sampler->observe(seq, [this](const std::string &id) { - return m_sinkContract->getDataItemById(id).get(); - }); - sampler->handlerCompleted(); - } - - publishCurrent(boost::system::error_code {}); - } - - /// @brief publish sample when observations arrive. - SequenceNumber_t Mqtt2Service::publishSample( - std::shared_ptr observer) - { - auto sampler = std::dynamic_pointer_cast(observer); - auto topic = formatTopic(m_sampleTopic, sampler->m_device); - LOG(debug) << "Publishing sample for: " << topic; - - std::unique_ptr observations; - SequenceNumber_t end {0}; - std::string doc; - SequenceNumber_t firstSeq, lastSeq; - - { - auto &buffer = m_sinkContract->getCircularBuffer(); - std::lock_guard lock(buffer); - - lastSeq = buffer.getSequence() - 1; - observations = - buffer.getObservations(m_sampleCount, sampler->getFilter(), sampler->getSequence(), - nullopt, end, firstSeq, observer->m_endOfBuffer); - } - - doc = m_printer->printSample(m_instanceId, - m_sinkContract->getCircularBuffer().getBufferSize(), end, - firstSeq, lastSeq, *observations, false); - - m_client->asyncPublish(topic, doc, [sampler, topic](std::error_code ec) { - if (!ec) - { - sampler->handlerCompleted(); - } - else - { - LOG(warning) << "Async publish failed for " << topic << ": " << ec.message(); - } - }); - - return end; - } - - void Mqtt2Service::publishCurrent(boost::system::error_code ec) - { - if (ec) - { - LOG(warning) << "Mqtt2Service::publishCurrent: " << ec.message(); - return; - } - - if (!m_client->isRunning() || !m_client->isConnected()) - { - LOG(warning) << "Mqtt2Service::publishCurrent: client stopped"; - return; - } - - for (auto &device : m_sinkContract->getDevices()) - { - auto topic = formatTopic(m_currentTopic, device); - LOG(debug) << "Publishing current for: " << topic; - - ObservationList observations; - SequenceNumber_t firstSeq, seq; - auto filterSet = filterForDevice(device); - - { - auto &buffer = m_sinkContract->getCircularBuffer(); - std::lock_guard lock(buffer); - - firstSeq = buffer.getFirstSequence(); - seq = buffer.getSequence(); - m_sinkContract->getCircularBuffer().getLatest().getObservations(observations, - filterSet); - } - - auto doc = m_printer->printSample(m_instanceId, - m_sinkContract->getCircularBuffer().getBufferSize(), - seq, firstSeq, seq - 1, observations); - - m_client->publish(topic, doc); - } - - using std::placeholders::_1; - m_currentTimer.expires_after(m_currentInterval); - m_currentTimer.async_wait(boost::asio::bind_executor( - m_strand, boost::bind(&Mqtt2Service::publishCurrent, this, _1))); - } - - bool Mqtt2Service::publish(observation::ObservationPtr &observation) - { - // Since we are doing periodic publishing, there is nothing to do here. - return true; - } - - bool Mqtt2Service::publish(device_model::DevicePtr device) - { - m_filters.clear(); - - auto topic = formatTopic(m_deviceTopic, device); - auto doc = m_jsonPrinter->print(device); - - stringstream buffer; - buffer << doc; - - if (m_client) - m_client->publish(topic, buffer.str()); - - return true; - } - - bool Mqtt2Service::publish(asset::AssetPtr asset) - { - auto uuid = asset->getDeviceUuid(); - DevicePtr dev; - if (uuid) - dev = m_sinkContract->findDeviceByUUIDorName(*uuid); - auto topic = formatTopic(m_assetTopic, dev); - if (topic.back() != '/') - topic.append("/"); - topic.append(asset->getAssetId()); - - LOG(debug) << "Publishing Asset to topic: " << topic; - - auto doc = m_jsonPrinter->print(asset); - - stringstream buffer; - buffer << doc; - - if (m_client) - m_client->publish(topic, buffer.str()); - - return true; - } - - // Register the service with the sink factory - void Mqtt2Service::registerFactory(SinkFactory &factory) - { - factory.registerFactory( - "Mqtt2Service", - [](const std::string &name, boost::asio::io_context &io, SinkContractPtr &&contract, - const ConfigOptions &options, const boost::property_tree::ptree &block) -> SinkPtr { - auto sink = std::make_shared(io, std::move(contract), options, block); - return sink; - }); - } - } // namespace mqtt_sink - } // namespace sink -} // namespace mtconnect diff --git a/src/mtconnect/sink/mqtt_sink/mqtt2_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt2_service.hpp deleted file mode 100644 index 0e1ddbab4..000000000 --- a/src/mtconnect/sink/mqtt_sink/mqtt2_service.hpp +++ /dev/null @@ -1,205 +0,0 @@ -// -// Copyright Copyright 2009-2023, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#pragma once - -#include "boost/asio/io_context.hpp" -#include - -#include - -#include "mtconnect/buffer/checkpoint.hpp" -#include "mtconnect/config.hpp" -#include "mtconnect/configuration/agent_config.hpp" -#include "mtconnect/entity/json_printer.hpp" -#include "mtconnect/mqtt/mqtt_client.hpp" -#include "mtconnect/observation/observation.hpp" -#include "mtconnect/printer//json_printer.hpp" -#include "mtconnect/printer/printer.hpp" -#include "mtconnect/printer/xml_printer_helper.hpp" -#include "mtconnect/sink/sink.hpp" -#include "mtconnect/utilities.hpp" - -using namespace std; -using namespace mtconnect; -using namespace mtconnect::entity; -using namespace mtconnect::mqtt_client; - -using json = nlohmann::json; - -namespace mtconnect { - class XmlPrinter; - - namespace sink { - - /// @brief MTConnect Mqtt implemention namespace - - namespace mqtt_sink { - - struct AsyncSample; - - class AGENT_LIB_API Mqtt2Service : public sink::Sink - { - // dynamic loading of sink - - public: - /// @brief Create a Mqtt Service sink - /// @param context the boost asio io_context - /// @param contract the Sink Contract from the agent - /// @param options configuration options - /// @param config additional configuration options if specified directly as a sink - Mqtt2Service(boost::asio::io_context &context, sink::SinkContractPtr &&contract, - const ConfigOptions &options, const boost::property_tree::ptree &config); - - ~Mqtt2Service() = default; - - // Sink Methods - /// @brief Start the Mqtt service - void start() override; - - /// @brief Shutdown the Mqtt service - void stop() override; - - /// @brief Receive an observation - /// - /// This does nothing since we are periodically publishing current and samples - /// - /// @param observation shared pointer to the observation - /// @return `true` if the publishing was successful - bool publish(observation::ObservationPtr &observation) override; - - /// @brief Receive an asset - /// @param asset shared point to the asset - /// @return `true` if successful - bool publish(asset::AssetPtr asset) override; - - /// @brief Receive a device - /// @param device shared pointer to the device - /// @return `true` if successful - bool publish(device_model::DevicePtr device) override; - - /// @brief Publsh all devices, assets, and begin async timer-based publishing - void pubishInitialContent(); - - /// @brief Publish a current using `CurrentInterval` option. - void publishCurrent(boost::system::error_code ec); - - /// @brief publish sample when observations arrive. - SequenceNumber_t publishSample(std::shared_ptr sampler); - - /// @brief Register the Sink factory to create this sink - /// @param factory - static void registerFactory(SinkFactory &factory); - - /// @brief gets a Mqtt Client - /// @return MqttClient - std::shared_ptr getClient() { return m_client; } - - /// @brief Mqtt Client is Connected or not - /// @return `true` when the client was connected - bool isConnected() { return m_client && m_client->isConnected(); } - - protected: - const FilterSet &filterForDevice(const DevicePtr &device) - { - auto filter = m_filters.find(*(device->getUuid())); - if (filter == m_filters.end()) - { - auto pos = m_filters.emplace(*(device->getUuid()), FilterSet()); - filter = pos.first; - auto &set = filter->second; - for (const auto &wdi : device->getDeviceDataItems()) - { - const auto di = wdi.lock(); - if (di) - set.insert(di->getId()); - } - } - return filter->second; - } - - std::string formatTopic(const std::string &topic, const DevicePtr device, - const std::string defaultUuid = "Unknown") - { - string uuid; - string formatted {topic}; - if (!device) - uuid = defaultUuid; - else - { - uuid = *(device->getUuid()); - if (std::dynamic_pointer_cast(device)) - { - uuid.insert(0, "Agent_"); - } - } - - if (formatted.find("[device]") == std::string::npos) - { - if (formatted.back() != '/') - formatted.append("/"); - formatted.append(uuid); - } - else - { - boost::replace_all(formatted, "[device]", uuid); - } - return formatted; - } - - std::string getTopic(const std::string &option, int maxTopicDepth) - { - auto topic {get(m_options[option])}; - auto depth = std::count(topic.begin(), topic.end(), '/'); - - if (depth > maxTopicDepth) - LOG(warning) << "Mqtt Option " << option - << " exceeds maximum number of levels: " << maxTopicDepth; - - return topic; - } - - protected: - std::string m_deviceTopic; //! Device topic prefix - std::string m_assetTopic; //! Asset topic prefix - std::string m_currentTopic; //! Current topic prefix - std::string m_sampleTopic; //! Sample topic prefix - std::string m_lastWillTopic; //! Topic to publish the last will when disconnected - - std::chrono::milliseconds m_currentInterval; //! Interval in ms to update current - std::chrono::milliseconds m_sampleInterval; //! min interval in ms to update sample - - uint64_t m_instanceId; - - boost::asio::io_context &m_context; - boost::asio::io_context::strand m_strand; - - ConfigOptions m_options; - - std::unique_ptr m_jsonPrinter; - std::unique_ptr m_printer; - - std::shared_ptr m_client; - boost::asio::steady_timer m_currentTimer; - int m_sampleCount; //! Timer for current requests - - std::map m_filters; - std::map> m_samplers; - }; - } // namespace mqtt_sink - } // namespace sink -} // namespace mtconnect diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp new file mode 100644 index 000000000..46aea8a12 --- /dev/null +++ b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp @@ -0,0 +1,197 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "mqtt_legacy_service.hpp" + +#include "mtconnect/configuration/config_options.hpp" +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/entity/factory.hpp" +#include "mtconnect/entity/json_parser.hpp" +#include "mtconnect/mqtt/mqtt_client_impl.hpp" +#include "mtconnect/printer/json_printer.hpp" + +using ptree = boost::property_tree::ptree; + +using namespace std; +using namespace mtconnect::asset; + +namespace asio = boost::asio; +namespace config = ::mtconnect::configuration; + +namespace mtconnect { + namespace sink { + namespace mqtt_sink { + // get obeservation in + // create a json printer + // call print + + MqttLegacyService::MqttLegacyService(boost::asio::io_context &context, + sink::SinkContractPtr &&contract, + const ConfigOptions &options, const ptree &config) + : Sink("MqttLegacyService", std::move(contract)), m_context(context), m_options(options) + { + auto jsonPrinter = dynamic_cast(m_sinkContract->getPrinter("json")); + m_jsonPrinter = make_unique(jsonPrinter->getJsonVersion()); + + GetOptions(config, m_options, options); + AddOptions(config, m_options, + {{configuration::ProbeTopic, string()}, + {configuration::MqttCaCert, string()}, + {configuration::MqttPrivateKey, string()}, + {configuration::MqttCert, string()}, + {configuration::MqttUserName, string()}, + {configuration::MqttPassword, string()}, + {configuration::MqttClientId, string()}}); + AddDefaultedOptions(config, m_options, + {{configuration::MqttHost, "127.0.0.1"s}, + {configuration::DeviceTopic, "MTConnect/Device/"s}, + {configuration::AssetTopic, "MTConnect/Asset/"s}, + {configuration::ObservationTopic, "MTConnect/Observation/"s}, + {configuration::MqttPort, 1883}, + {configuration::MqttTls, false}}); + + auto clientHandler = make_unique(); + clientHandler->m_connected = [this](shared_ptr client) { + // Publish latest devices, assets, and observations + auto &circ = m_sinkContract->getCircularBuffer(); + std::lock_guard lock(circ); + client->connectComplete(); + + for (auto &dev : m_sinkContract->getDevices()) + { + publish(dev); + } + + auto obsList {circ.getLatest().getObservations()}; + for (auto &obs : obsList) + { + observation::ObservationPtr p {obs.second}; + publish(p); + } + + AssetList list; + m_sinkContract->getAssetStorage()->getAssets(list, 100000); + for (auto &asset : list) + { + publish(asset); + } + }; + + m_devicePrefix = GetOption(m_options, configuration::ProbeTopic) + .value_or(get(m_options[configuration::DeviceTopic])); + m_assetPrefix = get(m_options[configuration::AssetTopic]); + m_observationPrefix = get(m_options[configuration::ObservationTopic]); + + if (IsOptionSet(m_options, configuration::MqttTls)) + { + m_client = make_shared(m_context, m_options, std::move(clientHandler)); + } + else + { + m_client = make_shared(m_context, m_options, std::move(clientHandler)); + } + } + + void MqttLegacyService::start() + { + // mqtt client side not a server side... + if (!m_client) + return; + + m_client->start(); + } + + void MqttLegacyService::stop() + { + // stop client side + if (m_client) + m_client->stop(); + } + + std::shared_ptr MqttLegacyService::getClient() { return m_client; } + + bool MqttLegacyService::publish(observation::ObservationPtr &observation) + { + // get the data item from observation + if (observation->isOrphan()) + return false; + + DataItemPtr dataItem = observation->getDataItem(); + + auto topic = m_observationPrefix + dataItem->getTopic(); // client asyn topic + auto content = dataItem->getTopicName(); // client asyn content + + // We may want to use the observation from the checkpoint. + string doc; + if (observation->getDataItem()->isCondition()) + { + doc = m_jsonPrinter->print(observation); + } + else + { + doc = m_jsonPrinter->printEntity(observation); + } + + if (m_client) + m_client->publish(topic, doc); + + return true; + } + + bool MqttLegacyService::publish(device_model::DevicePtr device) + { + auto topic = m_devicePrefix + *device->getUuid(); + auto doc = m_jsonPrinter->print(device); + + stringstream buffer; + buffer << doc; + + if (m_client) + m_client->publish(topic, buffer.str()); + + return true; + } + + bool MqttLegacyService::publish(asset::AssetPtr asset) + { + auto topic = m_assetPrefix + get(asset->getIdentity()); + auto doc = m_jsonPrinter->print(asset); + + stringstream buffer; + buffer << doc; + + if (m_client) + m_client->publish(topic, buffer.str()); + + return true; + } + + // Register the service with the sink factory + void MqttLegacyService::registerFactory(SinkFactory &factory) + { + factory.registerFactory( + "MqttLegacyService", + [](const std::string &name, boost::asio::io_context &io, SinkContractPtr &&contract, + const ConfigOptions &options, const boost::property_tree::ptree &block) -> SinkPtr { + auto sink = + std::make_shared(io, std::move(contract), options, block); + return sink; + }); + } + } // namespace mqtt_sink + } // namespace sink +} // namespace mtconnect diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp new file mode 100644 index 000000000..ab84d97d5 --- /dev/null +++ b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp @@ -0,0 +1,107 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include "boost/asio/io_context.hpp" +#include + +#include "mtconnect/buffer/checkpoint.hpp" +#include "mtconnect/config.hpp" +#include "mtconnect/configuration/agent_config.hpp" +#include "mtconnect/entity/json_printer.hpp" +#include "mtconnect/mqtt/mqtt_client.hpp" +#include "mtconnect/observation/observation.hpp" +#include "mtconnect/printer/printer.hpp" +#include "mtconnect/printer/xml_printer_helper.hpp" +#include "mtconnect/sink/sink.hpp" +#include "mtconnect/utilities.hpp" + +using namespace std; +using namespace mtconnect::entity; +using namespace mtconnect::mqtt_client; + +namespace mtconnect { + class XmlPrinter; + + namespace sink { + + /// @brief MTConnect Mqtt implemention namespace + + namespace mqtt_sink { + class AGENT_LIB_API MqttLegacyService : public sink::Sink + { + // dynamic loading of sink + + public: + /// @brief Create a Mqtt Service sink + /// @param context the boost asio io_context + /// @param contract the Sink Contract from the agent + /// @param options configuration options + /// @param config additional configuration options if specified directly as a sink + MqttLegacyService(boost::asio::io_context &context, sink::SinkContractPtr &&contract, + const ConfigOptions &options, const boost::property_tree::ptree &config); + + ~MqttLegacyService() = default; + + // Sink Methods + /// @brief Start the Mqtt service + void start() override; + + /// @brief Shutdown the Mqtt service + void stop() override; + + /// @brief Receive an observation + /// @param observation shared pointer to the observation + /// @return `true` if the publishing was successful + bool publish(observation::ObservationPtr &observation) override; + + /// @brief Receive an asset + /// @param asset shared point to the asset + /// @return `true` if successful + bool publish(asset::AssetPtr asset) override; + + /// @brief Receive a device + /// @param device shared pointer to the device + /// @return `true` if successful + bool publish(device_model::DevicePtr device) override; + + /// @brief Register the Sink factory to create this sink + /// @param factory + static void registerFactory(SinkFactory &factory); + + /// @brief gets a Mqtt Client + /// @return MqttClient + std::shared_ptr getClient(); + + /// @brief Mqtt Client is Connected or not + /// @return `true` when the client was connected + bool isConnected() { return m_client && m_client->isConnected(); } + + protected: + std::string m_devicePrefix; + std::string m_assetPrefix; + std::string m_observationPrefix; + + boost::asio::io_context &m_context; + ConfigOptions m_options; + std::unique_ptr m_jsonPrinter; + std::shared_ptr m_client; + }; + } // namespace mqtt_sink + } // namespace sink +} // namespace mtconnect diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp index b28b72d0f..7c17edbfd 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2023, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,6 +17,8 @@ #include "mqtt_service.hpp" +#include + #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/entity/entity.hpp" #include "mtconnect/entity/factory.hpp" @@ -25,8 +27,10 @@ #include "mtconnect/printer/json_printer.hpp" using ptree = boost::property_tree::ptree; +using json = nlohmann::json; using namespace std; +using namespace mtconnect; using namespace mtconnect::asset; namespace asio = boost::asio; @@ -41,119 +45,264 @@ namespace mtconnect { MqttService::MqttService(boost::asio::io_context &context, sink::SinkContractPtr &&contract, const ConfigOptions &options, const ptree &config) - : Sink("MqttService", std::move(contract)), m_context(context), m_options(options) + : Sink("MqttService", std::move(contract)), + m_context(context), + m_strand(context), + m_options(options), + m_currentTimer(context) { + // Unique id number for agent instance + m_instanceId = getCurrentTimeInSec(); + auto jsonPrinter = dynamic_cast(m_sinkContract->getPrinter("json")); + m_jsonPrinter = make_unique(jsonPrinter->getJsonVersion()); + m_printer = std::make_unique(jsonPrinter->getJsonVersion()); + GetOptions(config, m_options, options); AddOptions(config, m_options, {{configuration::ProbeTopic, string()}, {configuration::MqttCaCert, string()}, {configuration::MqttPrivateKey, string()}, {configuration::MqttCert, string()}, + {configuration::MqttClientId, string()}, {configuration::MqttUserName, string()}, - {configuration::MqttPassword, string()}, - {configuration::MqttClientId, string()}}); - AddDefaultedOptions(config, m_options, - {{configuration::MqttHost, "127.0.0.1"s}, - {configuration::DeviceTopic, "MTConnect/Device/"s}, - {configuration::AssetTopic, "MTConnect/Asset/"s}, - {configuration::ObservationTopic, "MTConnect/Observation/"s}, - {configuration::MqttPort, 1883}, - {configuration::MqttTls, false}}); - - auto clientHandler = make_unique(); - clientHandler->m_connected = [this](shared_ptr client) { - // Publish latest devices, assets, and observations - auto &circ = m_sinkContract->getCircularBuffer(); - std::lock_guard lock(circ); - client->connectComplete(); - - for (auto &dev : m_sinkContract->getDevices()) + {configuration::MqttPassword, string()}}); + AddDefaultedOptions( + config, m_options, + {{configuration::MqttHost, "127.0.0.1"s}, + {configuration::DeviceTopic, "MTConnect/Probe/[device]"s}, + {configuration::AssetTopic, "MTConnect/Asset/[device]"s}, + {configuration::MqttLastWillTopic, "MTConnect/Probe/[device]/Availability"s}, + {configuration::CurrentTopic, "MTConnect/Current/[device]"s}, + {configuration::SampleTopic, "MTConnect/Sample/[device]"s}, + {configuration::MqttCurrentInterval, 10000ms}, + {configuration::MqttSampleInterval, 500ms}, + {configuration::MqttSampleCount, 1000}, + {configuration::MqttPort, 1883}, + {configuration::MqttTls, false}}); + + int maxTopicDepth {GetOption(options, configuration::MqttMaxTopicDepth).value_or(7)}; + + m_deviceTopic = GetOption(m_options, configuration::ProbeTopic) + .value_or(get(m_options[configuration::DeviceTopic])); + m_assetTopic = getTopic(configuration::AssetTopic, maxTopicDepth); + m_currentTopic = getTopic(configuration::CurrentTopic, maxTopicDepth); + m_sampleTopic = getTopic(configuration::SampleTopic, maxTopicDepth); + + m_currentInterval = *GetOption(m_options, configuration::MqttCurrentInterval); + m_sampleInterval = *GetOption(m_options, configuration::MqttSampleInterval); + + m_sampleCount = *GetOption(m_options, configuration::MqttSampleCount); + } + + void MqttService::start() + { + if (!m_client) + { + auto clientHandler = make_unique(); + clientHandler->m_connected = [this](shared_ptr client) { + // Publish latest devices, assets, and observations + auto &circ = m_sinkContract->getCircularBuffer(); + std::lock_guard lock(circ); + client->connectComplete(); + + client->publish(m_lastWillTopic, "AVAILABLE"); + pubishInitialContent(); + }; + + auto agentDevice = m_sinkContract->getDeviceByName("Agent"); + auto lwtTopic = get(m_options[configuration::MqttLastWillTopic]); + m_lastWillTopic = formatTopic(lwtTopic, agentDevice, "Agent"); + + if (IsOptionSet(m_options, configuration::MqttTls)) { - publish(dev); + m_client = make_shared(m_context, m_options, std::move(clientHandler), + m_lastWillTopic, "UNAVAILABLE"s); } - - auto obsList {circ.getLatest().getObservations()}; - for (auto &obs : obsList) + else { - observation::ObservationPtr p {obs.second}; - publish(p); + m_client = make_shared(m_context, m_options, std::move(clientHandler), + m_lastWillTopic, "UNAVAILABLE"s); } + } + m_client->start(); + } + + void MqttService::stop() + { + // stop client side + if (m_client) + m_client->stop(); + + m_currentTimer.cancel(); + } + + struct AsyncSample : public observation::AsyncObserver + { + AsyncSample(boost::asio::io_context::strand &strand, + mtconnect::buffer::CircularBuffer &buffer, FilterSet &&filter, + std::chrono::milliseconds interval, std::chrono::milliseconds heartbeat, + std::shared_ptr client, DevicePtr device) + : observation::AsyncObserver(strand, buffer, std::move(filter), interval, heartbeat), + m_device(device), + m_client(client) + {} + + void fail(boost::beast::http::status status, const std::string &message) override + { + LOG(error) << "MQTT Sample Failed: " << message; + } + + bool isRunning() override + { + if (m_sink.expired()) + return false; + + auto client = m_client.lock(); + return client && client->isRunning() && client->isConnected(); + } + + bool cancel() override { return true; } + + DevicePtr m_device; + std::weak_ptr m_client; + std::weak_ptr + m_sink; //! weak shared pointer to the sink. handles shutdown timer race + }; + + void MqttService::pubishInitialContent() + { + using std::placeholders::_1; + for (auto &dev : m_sinkContract->getDevices()) + { + publish(dev); AssetList list; - m_sinkContract->getAssetStorage()->getAssets(list, 100000); + m_sinkContract->getAssetStorage()->getAssets(list, 100000, true, *(dev->getUuid())); for (auto &asset : list) { publish(asset); } - }; - - m_devicePrefix = GetOption(m_options, configuration::ProbeTopic) - .value_or(get(m_options[configuration::DeviceTopic])); - m_assetPrefix = get(m_options[configuration::AssetTopic]); - m_observationPrefix = get(m_options[configuration::ObservationTopic]); - - if (IsOptionSet(m_options, configuration::MqttTls)) - { - m_client = make_shared(m_context, m_options, std::move(clientHandler)); } - else + + auto seq = m_sinkContract->getCircularBuffer().getSequence(); + for (auto &dev : m_sinkContract->getDevices()) { - m_client = make_shared(m_context, m_options, std::move(clientHandler)); + FilterSet filterSet = filterForDevice(dev); + auto sampler = + make_shared(m_strand, m_sinkContract->getCircularBuffer(), + std::move(filterSet), m_sampleInterval, 600s, m_client, dev); + sampler->m_sink = getptr(); + sampler->m_handler = boost::bind(&MqttService::publishSample, this, _1); + sampler->observe(seq, [this](const std::string &id) { + return m_sinkContract->getDataItemById(id).get(); + }); + sampler->handlerCompleted(); } + + publishCurrent(boost::system::error_code {}); } - void MqttService::start() + /// @brief publish sample when observations arrive. + SequenceNumber_t MqttService::publishSample( + std::shared_ptr observer) { - // mqtt client side not a server side... - if (!m_client) - return; + auto sampler = std::dynamic_pointer_cast(observer); + auto topic = formatTopic(m_sampleTopic, sampler->m_device); + LOG(debug) << "Publishing sample for: " << topic; - m_client->start(); - } + std::unique_ptr observations; + SequenceNumber_t end {0}; + std::string doc; + SequenceNumber_t firstSeq, lastSeq; - void MqttService::stop() - { - // stop client side - if (m_client) - m_client->stop(); - } + { + auto &buffer = m_sinkContract->getCircularBuffer(); + std::lock_guard lock(buffer); - std::shared_ptr MqttService::getClient() { return m_client; } + lastSeq = buffer.getSequence() - 1; + observations = + buffer.getObservations(m_sampleCount, sampler->getFilter(), sampler->getSequence(), + nullopt, end, firstSeq, observer->m_endOfBuffer); + } - bool MqttService::publish(observation::ObservationPtr &observation) - { - // get the data item from observation - if (observation->isOrphan()) - return false; + doc = m_printer->printSample(m_instanceId, + m_sinkContract->getCircularBuffer().getBufferSize(), end, + firstSeq, lastSeq, *observations, false); - DataItemPtr dataItem = observation->getDataItem(); + m_client->asyncPublish(topic, doc, [sampler, topic](std::error_code ec) { + if (!ec) + { + sampler->handlerCompleted(); + } + else + { + LOG(warning) << "Async publish failed for " << topic << ": " << ec.message(); + } + }); - auto topic = m_observationPrefix + dataItem->getTopic(); // client asyn topic - auto content = dataItem->getTopicName(); // client asyn content + return end; + } - // We may want to use the observation from the checkpoint. - string doc; - if (observation->getDataItem()->isCondition()) + void MqttService::publishCurrent(boost::system::error_code ec) + { + if (ec) { - doc = m_jsonPrinter->print(observation); + LOG(warning) << "Mqtt2Service::publishCurrent: " << ec.message(); + return; } - else + + if (!m_client->isRunning() || !m_client->isConnected()) { - doc = m_jsonPrinter->printEntity(observation); + LOG(warning) << "Mqtt2Service::publishCurrent: client stopped"; + return; } - if (m_client) + for (auto &device : m_sinkContract->getDevices()) + { + auto topic = formatTopic(m_currentTopic, device); + LOG(debug) << "Publishing current for: " << topic; + + ObservationList observations; + SequenceNumber_t firstSeq, seq; + auto filterSet = filterForDevice(device); + + { + auto &buffer = m_sinkContract->getCircularBuffer(); + std::lock_guard lock(buffer); + + firstSeq = buffer.getFirstSequence(); + seq = buffer.getSequence(); + m_sinkContract->getCircularBuffer().getLatest().getObservations(observations, + filterSet); + } + + auto doc = m_printer->printSample(m_instanceId, + m_sinkContract->getCircularBuffer().getBufferSize(), + seq, firstSeq, seq - 1, observations); + m_client->publish(topic, doc); + } + + using std::placeholders::_1; + m_currentTimer.expires_after(m_currentInterval); + m_currentTimer.async_wait(boost::asio::bind_executor( + m_strand, boost::bind(&MqttService::publishCurrent, this, _1))); + } + bool MqttService::publish(observation::ObservationPtr &observation) + { + // Since we are doing periodic publishing, there is nothing to do here. return true; } bool MqttService::publish(device_model::DevicePtr device) { - auto topic = m_devicePrefix + *device->getUuid(); + m_filters.clear(); + + auto topic = formatTopic(m_deviceTopic, device); auto doc = m_jsonPrinter->print(device); stringstream buffer; @@ -167,7 +316,17 @@ namespace mtconnect { bool MqttService::publish(asset::AssetPtr asset) { - auto topic = m_assetPrefix + get(asset->getIdentity()); + auto uuid = asset->getDeviceUuid(); + DevicePtr dev; + if (uuid) + dev = m_sinkContract->findDeviceByUUIDorName(*uuid); + auto topic = formatTopic(m_assetTopic, dev); + if (topic.back() != '/') + topic.append("/"); + topic.append(asset->getAssetId()); + + LOG(debug) << "Publishing Asset to topic: " << topic; + auto doc = m_jsonPrinter->print(asset); stringstream buffer; diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp index e94d01f55..6cba52409 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2023, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,21 +20,27 @@ #include "boost/asio/io_context.hpp" #include +#include + #include "mtconnect/buffer/checkpoint.hpp" #include "mtconnect/config.hpp" #include "mtconnect/configuration/agent_config.hpp" #include "mtconnect/entity/json_printer.hpp" #include "mtconnect/mqtt/mqtt_client.hpp" #include "mtconnect/observation/observation.hpp" +#include "mtconnect/printer//json_printer.hpp" #include "mtconnect/printer/printer.hpp" #include "mtconnect/printer/xml_printer_helper.hpp" #include "mtconnect/sink/sink.hpp" #include "mtconnect/utilities.hpp" using namespace std; +using namespace mtconnect; using namespace mtconnect::entity; using namespace mtconnect::mqtt_client; +using json = nlohmann::json; + namespace mtconnect { class XmlPrinter; @@ -43,6 +49,9 @@ namespace mtconnect { /// @brief MTConnect Mqtt implemention namespace namespace mqtt_sink { + + struct AsyncSample; + class AGENT_LIB_API MqttService : public sink::Sink { // dynamic loading of sink @@ -66,6 +75,9 @@ namespace mtconnect { void stop() override; /// @brief Receive an observation + /// + /// This does nothing since we are periodically publishing current and samples + /// /// @param observation shared pointer to the observation /// @return `true` if the publishing was successful bool publish(observation::ObservationPtr &observation) override; @@ -80,27 +92,113 @@ namespace mtconnect { /// @return `true` if successful bool publish(device_model::DevicePtr device) override; + /// @brief Publsh all devices, assets, and begin async timer-based publishing + void pubishInitialContent(); + + /// @brief Publish a current using `CurrentInterval` option. + void publishCurrent(boost::system::error_code ec); + + /// @brief publish sample when observations arrive. + SequenceNumber_t publishSample(std::shared_ptr sampler); + /// @brief Register the Sink factory to create this sink /// @param factory static void registerFactory(SinkFactory &factory); /// @brief gets a Mqtt Client /// @return MqttClient - std::shared_ptr getClient(); + std::shared_ptr getClient() { return m_client; } /// @brief Mqtt Client is Connected or not /// @return `true` when the client was connected bool isConnected() { return m_client && m_client->isConnected(); } protected: - std::string m_devicePrefix; - std::string m_assetPrefix; - std::string m_observationPrefix; + const FilterSet &filterForDevice(const DevicePtr &device) + { + auto filter = m_filters.find(*(device->getUuid())); + if (filter == m_filters.end()) + { + auto pos = m_filters.emplace(*(device->getUuid()), FilterSet()); + filter = pos.first; + auto &set = filter->second; + for (const auto &wdi : device->getDeviceDataItems()) + { + const auto di = wdi.lock(); + if (di) + set.insert(di->getId()); + } + } + return filter->second; + } + + std::string formatTopic(const std::string &topic, const DevicePtr device, + const std::string defaultUuid = "Unknown") + { + string uuid; + string formatted {topic}; + if (!device) + uuid = defaultUuid; + else + { + uuid = *(device->getUuid()); + if (std::dynamic_pointer_cast(device)) + { + uuid.insert(0, "Agent_"); + } + } + + if (formatted.find("[device]") == std::string::npos) + { + if (formatted.back() != '/') + formatted.append("/"); + formatted.append(uuid); + } + else + { + boost::replace_all(formatted, "[device]", uuid); + } + return formatted; + } + + std::string getTopic(const std::string &option, int maxTopicDepth) + { + auto topic {get(m_options[option])}; + auto depth = std::count(topic.begin(), topic.end(), '/'); + + if (depth > maxTopicDepth) + LOG(warning) << "Mqtt Option " << option + << " exceeds maximum number of levels: " << maxTopicDepth; + + return topic; + } + + protected: + std::string m_deviceTopic; //! Device topic prefix + std::string m_assetTopic; //! Asset topic prefix + std::string m_currentTopic; //! Current topic prefix + std::string m_sampleTopic; //! Sample topic prefix + std::string m_lastWillTopic; //! Topic to publish the last will when disconnected + + std::chrono::milliseconds m_currentInterval; //! Interval in ms to update current + std::chrono::milliseconds m_sampleInterval; //! min interval in ms to update sample + + uint64_t m_instanceId; boost::asio::io_context &m_context; + boost::asio::io_context::strand m_strand; + ConfigOptions m_options; + std::unique_ptr m_jsonPrinter; + std::unique_ptr m_printer; + std::shared_ptr m_client; + boost::asio::steady_timer m_currentTimer; + int m_sampleCount; //! Timer for current requests + + std::map m_filters; + std::map> m_samplers; }; } // namespace mqtt_sink } // namespace sink diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 389e34cea..48905e154 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -115,7 +115,8 @@ namespace mtconnect { {"pretty", QUERY, "Instructs the result to be pretty printed"}, {"format", QUERY, "The format of the response document: 'xml' or 'json'"}, {"heartbeat", QUERY, - "Time in ms between publishing a empty document when no data has changed"}}); + "Time in ms between publishing a empty document when no data has changed"}, + {"requestId", PATH, "webservice request id"}}); createProbeRoutings(); createCurrentRoutings(); @@ -760,6 +761,11 @@ namespace mtconnect { return true; }; + auto cancelHandler = [&](SessionPtr session, RequestPtr request) -> bool { + auto requestId = *request->parameter("requestId"); + return session->cancelRequest(requestId); + }; + string qp( "path={string}&from={unsigned_integer}&" "interval={integer}&count={integer:100}&" @@ -777,6 +783,9 @@ namespace mtconnect { "optionally filtered by the `path` and starting at `from`. By default, from is " "the first available observation known to the agent") .command("sample"); + m_server + ->addRouting({boost::beast::http::verb::get, "/cancel/requestId={string}", cancelHandler}) + .document("MTConnect WebServices Cancel Stream", "Cancels a streaming sample request"); } void RestService::createPutObservationRoutings() @@ -960,11 +969,11 @@ namespace mtconnect { return server->isRunning(); } } - + bool cancel() override { observation::AsyncObserver::cancel(); - m_session.reset(); + m_session.reset(); return true; } @@ -976,7 +985,6 @@ namespace mtconnect { rest_sink::SessionPtr m_session; ofstream m_log; bool m_pretty {false}; - std::optional m_requestId; }; void RestService::streamSampleRequest(rest_sink::SessionPtr session, const Printer *printer, @@ -1019,7 +1027,7 @@ namespace mtconnect { asyncResponse->m_printer = printer; asyncResponse->m_sink = getptr(); asyncResponse->m_pretty = pretty; - asyncResponse->m_requestId = requestId; + asyncResponse->setRequestId(requestId); session->addObserver(asyncResponse); if (m_logStreamData) @@ -1064,7 +1072,7 @@ namespace mtconnect { string content = fetchSampleData(asyncResponse->m_printer, asyncResponse->getFilter(), asyncResponse->m_count, from, nullopt, end, asyncObserver->m_endOfBuffer, asyncResponse->m_pretty, - asyncResponse->m_requestId); + asyncResponse->getRequestId()); if (m_logStreamData) asyncResponse->m_log << content << endl; @@ -1073,7 +1081,7 @@ namespace mtconnect { content, asio::bind_executor(m_strand, boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), - asyncResponse->m_requestId); + asyncResponse->getRequestId()); return end; } diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index 8d3f76412..ba690894f 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -118,13 +118,27 @@ namespace mtconnect::sink::rest_sink { m_message = msg; m_unauthorized = true; } - + /// @brief Add an observer to the list for cleanup later. void addObserver(std::weak_ptr observer) { m_observers.push_back(observer); } + bool cancelRequest(const std::string &requestId) + { + for (auto &obs : m_observers) + { + auto pobs = obs.lock(); + if (pobs && pobs->getRequestId() == requestId) + { + pobs->cancel(); + return true; + } + } + return false; + } + protected: Dispatch m_dispatch; ErrorFunction m_errorFunction; diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index f1eeef2e5..cdd04d2e8 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -527,7 +527,7 @@ namespace mtconnect::sink::rest_sink { if (!m_closing) { m_closing = true; - + // Release all references from observers. for (auto obs : m_observers) { @@ -538,7 +538,6 @@ namespace mtconnect::sink::rest_sink { } } - // Set the timeout. beast::get_lowest_layer(m_stream).expires_after(std::chrono::seconds(30)); diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index e38b0c4dd..f06b916c8 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -96,15 +96,15 @@ namespace mtconnect::sink::rest_sink { beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr()))); } - + void close() override { NAMED_SCOPE("PlainWebsocketSession::close"); if (!m_isOpen) return; - + auto ptr = derived().shared_ptr(); - + m_request.reset(); m_requests.clear(); for (auto obs : m_observers) @@ -116,7 +116,7 @@ namespace mtconnect::sink::rest_sink { } } closeStream(); - + m_isOpen = false; } @@ -170,12 +170,12 @@ namespace mtconnect::sink::rest_sink { std::optional requestId = std::nullopt) override { NAMED_SCOPE("WebsocketSession::writeChunk"); - + if (!derived().stream().is_open()) { return; } - + if (requestId) { LOG(trace) << "Waiting for mutex"; @@ -204,7 +204,7 @@ namespace mtconnect::sink::rest_sink { fail(status::internal_server_error, "Error occurred in accpet", ec); return; } - + m_isOpen = true; derived().stream().async_read( @@ -311,7 +311,7 @@ namespace mtconnect::sink::rest_sink { using namespace rapidjson; using namespace std; - + if (len == 0) { LOG(trace) << "Empty message received"; @@ -435,7 +435,7 @@ namespace mtconnect::sink::rest_sink { std::mutex m_mutex; std::atomic_bool m_busy; std::deque m_messageQueue; - bool m_isOpen { false }; + bool m_isOpen {false}; }; template @@ -453,8 +453,8 @@ namespace mtconnect::sink::rest_sink { { beast::get_lowest_layer(m_stream).expires_never(); } - ~PlainWebsocketSession() - { + ~PlainWebsocketSession() + { if (m_isOpen) close(); } @@ -492,12 +492,12 @@ namespace mtconnect::sink::rest_sink { { beast::get_lowest_layer(m_stream).expires_never(); } - ~TlsWebsocketSession() + ~TlsWebsocketSession() { if (m_isOpen) close(); } - + auto &stream() { return m_stream; } auto getExecutor() { return m_stream.get_executor(); } diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index 08a4e1ffd..ec5961013 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -249,8 +249,8 @@ add_agent_test(tls_http_server FALSE sink/rest_sink TRUE) add_agent_test(routing FALSE sink/rest_sink) add_agent_test(mqtt_isolated FALSE mqtt_isolated TRUE) +add_agent_test(mqtt_legacy_sink FALSE sink/mqtt_legacy_sink TRUE) add_agent_test(mqtt_sink FALSE sink/mqtt_sink TRUE) -add_agent_test(mqtt_sink_2 FALSE sink/mqtt_sink_2 TRUE) add_agent_test(json_printer_asset TRUE json) add_agent_test(json_printer_error TRUE json) diff --git a/test_package/agent_test_helper.hpp b/test_package/agent_test_helper.hpp index a0f93a0bb..4d16eb475 100644 --- a/test_package/agent_test_helper.hpp +++ b/test_package/agent_test_helper.hpp @@ -29,7 +29,7 @@ #include "mtconnect/configuration/agent_config.hpp" #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/pipeline/pipeline.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt2_service.hpp" +#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" #include "mtconnect/sink/mqtt_sink/mqtt_service.hpp" #include "mtconnect/sink/rest_sink/response.hpp" #include "mtconnect/sink/rest_sink/rest_service.hpp" @@ -124,8 +124,8 @@ class AgentTestHelper ~AgentTestHelper() { + m_mqttLegacyService.reset(); m_mqttService.reset(); - m_mqtt2Service.reset(); m_restService.reset(); m_adapter.reset(); if (m_agent) @@ -171,21 +171,21 @@ class AgentTestHelper return rest; } - std::shared_ptr getMqttService() + std::shared_ptr getMqttLegacyService() { using namespace mtconnect; - sink::SinkPtr sink = m_agent->findSink("MqttService"); - std::shared_ptr mqtt = - std::dynamic_pointer_cast(sink); + sink::SinkPtr sink = m_agent->findSink("MqttLegacyService"); + std::shared_ptr mqtt = + std::dynamic_pointer_cast(sink); return mqtt; } - std::shared_ptr getMqtt2Service() + std::shared_ptr getMqttService() { using namespace mtconnect; - sink::SinkPtr mqttSink = m_agent->findSink("Mqtt2Service"); - std::shared_ptr mqtt2 = - std::dynamic_pointer_cast(mqttSink); + sink::SinkPtr mqttSink = m_agent->findSink("MqttService"); + std::shared_ptr mqtt2 = + std::dynamic_pointer_cast(mqttSink); return mqtt2; } @@ -199,8 +199,8 @@ class AgentTestHelper using ptree = boost::property_tree::ptree; sink::rest_sink::RestService::registerFactory(m_sinkFactory); + sink::mqtt_sink::MqttLegacyService::registerFactory(m_sinkFactory); sink::mqtt_sink::MqttService::registerFactory(m_sinkFactory); - sink::mqtt_sink::Mqtt2Service::registerFactory(m_sinkFactory); source::adapter::shdr::ShdrAdapter::registerFactory(m_sourceFactory); ConfigOptions options = ops; @@ -232,24 +232,24 @@ class AgentTestHelper m_restService = std::dynamic_pointer_cast(sink); m_agent->addSink(m_restService); - if (HasOption(options, "MqttSink")) + if (HasOption(options, "MqttLegacySink")) { auto mqttContract = m_agent->makeSinkContract(); mqttContract->m_pipelineContext = m_context; - auto mqttsink = m_sinkFactory.make("MqttService", "MqttService", m_ioContext, + auto mqttsink = m_sinkFactory.make("MqttLegacyService", "MqttLegacyService", m_ioContext, std::move(mqttContract), options, ptree {}); - m_mqttService = std::dynamic_pointer_cast(mqttsink); - m_agent->addSink(m_mqttService); + m_mqttLegacyService = std::dynamic_pointer_cast(mqttsink); + m_agent->addSink(m_mqttLegacyService); } - if (HasOption(options, "Mqtt2Sink")) + if (HasOption(options, "MqttSink")) { auto mqttContract = m_agent->makeSinkContract(); mqttContract->m_pipelineContext = m_context; - auto mqtt2sink = m_sinkFactory.make("Mqtt2Service", "Mqtt2Service", m_ioContext, + auto mqtt2sink = m_sinkFactory.make("MqttService", "MqttService", m_ioContext, std::move(mqttContract), options, ptree {}); - m_mqtt2Service = std::dynamic_pointer_cast(mqtt2sink); - m_agent->addSink(m_mqtt2Service); + m_mqttService = std::dynamic_pointer_cast(mqtt2sink); + m_agent->addSink(m_mqttService); } m_agent->initialize(m_context); @@ -324,8 +324,8 @@ class AgentTestHelper mhttp::Server *m_server {nullptr}; std::shared_ptr m_context; std::shared_ptr m_adapter; + std::shared_ptr m_mqttLegacyService; std::shared_ptr m_mqttService; - std::shared_ptr m_mqtt2Service; std::shared_ptr m_restService; std::shared_ptr m_loopback; diff --git a/test_package/mqtt_isolated_test.cpp b/test_package/mqtt_isolated_test.cpp index 9789436c5..4e7cbc566 100644 --- a/test_package/mqtt_isolated_test.cpp +++ b/test_package/mqtt_isolated_test.cpp @@ -181,7 +181,7 @@ class MqttIsolatedUnitTest : public testing::Test std::unique_ptr m_jsonPrinter; std::shared_ptr m_server; std::shared_ptr m_client; - std::shared_ptr m_service; + std::shared_ptr m_service; std::unique_ptr m_agentTestHelper; uint16_t m_port {0}; }; diff --git a/test_package/mqtt_legacy_sink_test.cpp b/test_package/mqtt_legacy_sink_test.cpp new file mode 100644 index 000000000..4647c924e --- /dev/null +++ b/test_package/mqtt_legacy_sink_test.cpp @@ -0,0 +1,630 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/// @file +/// Test MQTT 1 Service + +// Ensure that gtest is the first header otherwise Windows raises an error +#include +// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) + +#include + +#include + +#include "agent_test_helper.hpp" +#include "mtconnect/buffer/checkpoint.hpp" +#include "mtconnect/device_model/data_item/data_item.hpp" +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/entity/json_parser.hpp" +#include "mtconnect/mqtt/mqtt_client_impl.hpp" +#include "mtconnect/mqtt/mqtt_server_impl.hpp" +#include "mtconnect/printer//json_printer.hpp" +#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" + +using namespace std; +using namespace mtconnect; +using namespace mtconnect::device_model::data_item; +using namespace mtconnect::sink::mqtt_sink; +using namespace mtconnect::asset; +using namespace mtconnect::configuration; + +// main +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +using json = nlohmann::json; + +class MqttSinkTest : public testing::Test +{ +protected: + void SetUp() override + { + m_agentTestHelper = make_unique(); + m_jsonPrinter = std::make_unique(2, true); + } + + void TearDown() override + { + const auto agent = m_agentTestHelper->getAgent(); + if (agent) + { + m_agentTestHelper->getAgent()->stop(); + m_agentTestHelper->m_ioContext.run_for(100ms); + } + if (m_client) + { + m_client->stop(); + m_agentTestHelper->m_ioContext.run_for(100ms); + m_client.reset(); + } + if (m_server) + { + m_server->stop(); + m_agentTestHelper->m_ioContext.run_for(500ms); + m_server.reset(); + } + m_agentTestHelper.reset(); + m_jsonPrinter.reset(); + } + + void createAgent(std::string testFile = {}, ConfigOptions options = {}) + { + if (testFile == "") + testFile = "/samples/test_config.xml"; + + ConfigOptions opts(options); + MergeOptions(opts, {{"MqttLegacySink", true}, + {configuration::MqttPort, m_port}, + {configuration::MqttHost, "127.0.0.1"s}}); + m_agentTestHelper->createAgent(testFile, 8, 4, "2.0", 25, false, true, opts); + addAdapter(); + + m_agentTestHelper->getAgent()->start(); + } + + void createServer(const ConfigOptions &options) + { + using namespace mtconnect::configuration; + ConfigOptions opts(options); + MergeOptions(opts, {{ServerIp, "127.0.0.1"s}, + {MqttPort, 0}, + {MqttTls, false}, + {AutoAvailable, false}, + {RealTime, false}}); + + m_server = + make_shared(m_agentTestHelper->m_ioContext, opts); + } + + template + bool waitFor(const chrono::duration &time, function pred) + { + boost::asio::steady_timer timer(m_agentTestHelper->m_ioContext); + timer.expires_from_now(time); + bool timeout = false; + timer.async_wait([&timeout](boost::system::error_code ec) { + if (!ec) + { + timeout = true; + } + }); + + while (!timeout && !pred()) + { + m_agentTestHelper->m_ioContext.run_for(100ms); + } + timer.cancel(); + + return pred(); + } + + void startServer() + { + if (m_server) + { + bool start = m_server->start(); + if (start) + { + m_port = m_server->getPort(); + m_agentTestHelper->m_ioContext.run_for(500ms); + } + } + } + + void createClient(const ConfigOptions &options, unique_ptr &&handler) + { + ConfigOptions opts(options); + MergeOptions(opts, {{MqttHost, "127.0.0.1"s}, + {MqttPort, m_port}, + {MqttTls, false}, + {AutoAvailable, false}, + {RealTime, false}}); + m_client = make_shared(m_agentTestHelper->m_ioContext, + opts, std::move(handler)); + } + + bool startClient() + { + bool started = m_client && m_client->start(); + if (started) + { + return waitFor(5s, [this]() { return m_client->isConnected(); }); + } + return started; + } + + void addAdapter(ConfigOptions options = ConfigOptions {}) + { + m_agentTestHelper->addAdapter(options, "localhost", 0, + m_agentTestHelper->m_agent->getDefaultDevice()->getName()); + } + + std::unique_ptr m_jsonPrinter; + std::shared_ptr m_server; + std::shared_ptr m_client; + std::shared_ptr m_service; + std::unique_ptr m_agentTestHelper; + uint16_t m_port {0}; +}; + +TEST_F(MqttSinkTest, mqtt_sink_should_be_loaded_by_agent) +{ + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + + ASSERT_TRUE(service); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker) +{ + ConfigOptions options; + createServer(options); + startServer(); + + ASSERT_NE(0, m_port); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_with_UserNameandPassword) +{ + ConfigOptions options {{MqttUserName, "MQTT-SINK"s}, {MqttPassword, "mtconnect"s}}; + createServer(options); + startServer(); + + ASSERT_NE(0, m_port); + + createAgent("", options); + auto service = m_agentTestHelper->getMqttLegacyService(); + + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_without_UserNameandPassword) +{ + ConfigOptions options; + createServer(options); + startServer(); + + ASSERT_NE(0, m_port); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_device) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool gotDevice = false; + handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, + const std::string &topic, const std::string &payload) { + EXPECT_EQ("MTConnect/Device/000", topic); + + ErrorList list; + auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); + EXPECT_EQ(0, list.size()); + auto dev = dynamic_pointer_cast(ptr); + EXPECT_TRUE(dev); + EXPECT_EQ("LinuxCNC", dev->getComponentName()); + EXPECT_EQ("000", *dev->getUuid()); + + gotDevice = true; + }; + + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + m_client->subscribe("MTConnect/Device/000"); + + createAgent(); + + auto service = m_agentTestHelper->getMqttLegacyService(); + + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + + ASSERT_TRUE(waitFor(5s, [&gotDevice]() { return gotDevice; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Streams) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool foundLineDataItem = false; + handler->m_receive = [&foundLineDataItem](std::shared_ptr client, + const std::string &topic, const std::string &payload) { + EXPECT_EQ("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]", topic); + + auto jdoc = json::parse(payload); + string value = jdoc.at("/value"_json_pointer).get(); + EXPECT_EQ("204", value); + foundLineDataItem = true; + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + + m_client->subscribe("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]"); + m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); + + ASSERT_TRUE(waitFor(5s, [&foundLineDataItem]() { return foundLineDataItem; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Asset) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool gotControllerDataItem = false; + handler->m_receive = [&gotControllerDataItem](std::shared_ptr, + const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Asset/0001", topic); + auto jdoc = json::parse(payload); + string id = jdoc.at("/Part/assetId"_json_pointer).get(); + EXPECT_EQ("0001", id); + gotControllerDataItem = true; + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe("MTConnect/Asset/0001"); + + m_agentTestHelper->m_adapter->processData( + "2021-02-01T12:00:00Z|@ASSET@|@1|Part|TEST 1"); + + ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_RotaryMode) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool gotRotaryMode = false; + handler->m_receive = [&gotRotaryMode](std::shared_ptr, const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]", + topic); + auto jdoc = json::parse(payload); + + double v = jdoc.at("/value"_json_pointer).get(); + EXPECT_EQ(5000.0, v); + gotRotaryMode = true; + }; + + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe( + "MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]"); + + m_agentTestHelper->m_adapter->processData( + "2021-02-01T12:00:00Z|block|G01X00|Sspeed|5000|line|204"); + + ASSERT_TRUE(waitFor(5s, [&gotRotaryMode]() { return gotRotaryMode; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Dataset) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + entity::JsonParser parser; + auto handler = make_unique(); + bool gotControllerDataItem = false; + handler->m_receive = [&gotControllerDataItem](std::shared_ptr, + const std::string &topic, + const std::string &payload) { + EXPECT_EQ( + "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]", + topic); + auto jdoc = json::parse(payload); + auto id = jdoc.at("/value/a"_json_pointer).get(); + EXPECT_EQ(1, id); + gotControllerDataItem = true; + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + createAgent("/samples/data_set.xml"); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe( + "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]"); + + m_agentTestHelper->m_adapter->processData("TIME|vars|a=1 b=2 c=3"); + ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Table) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + entity::JsonParser parser; + auto handler = make_unique(); + bool gotControllerDataItem = false; + handler->m_receive = [&gotControllerDataItem](std::shared_ptr, + const std::string &topic, + const std::string &payload) { + EXPECT_EQ( + "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/WorkOffsetTable[wpo]", + topic); + auto jdoc = json::parse(payload); + + auto jValue = jdoc.at("/value"_json_pointer); + int count = 0; + if (jValue.is_object()) + { + for (auto &[key, value] : jValue.items()) + { + if (key == "G53.1" || key == "G53.2" || key == "G53.3") + { + for (auto &[subKey, subValue] : value.items()) + { + if (key == "G53.1" && ((subKey == "X" && subValue.get() == 1) || + (subKey == "Y" && subValue.get() == 2) || + (subKey == "Z" && subValue.get() == 3))) + { + count++; + } + else if (key == "G53.2" && ((subKey == "X" && subValue.get() == 4) || + (subKey == "Y" && subValue.get() == 5) || + (subKey == "Z" && subValue.get() == 6))) + { + count++; + } + else if (key == "G53.3" && ((subKey == "X" && subValue.get() == 7.0) || + (subKey == "Y" && subValue.get() == 8.0) || + (subKey == "Z" && subValue.get() == 9.0) || + (subKey == "U" && subValue.get() == 10.0))) + { + count++; + } + } + } + } + EXPECT_EQ(10, count); + gotControllerDataItem = true; + } + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + createAgent("/samples/data_set.xml"); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe( + "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/" + "WorkOffsetTable[wpo]"); + + m_agentTestHelper->m_adapter->processData( + "2021-02-01T12:00:00Z|wpo|G53.1={X=1.0 Y=2.0 Z=3.0} G53.2={X=4.0 Y=5.0 Z=6.0}" + "G53.3={X=7.0 Y=8.0 Z=9 U=10.0}"); + + ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Temperature) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool gotTemperature = false; + handler->m_receive = [&gotTemperature](std::shared_ptr, const std::string &topic, + const std::string &payload) { + EXPECT_EQ( + "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" + "Temperature[z_motor_temp]", + topic); + auto jdoc = json::parse(payload); + + auto value = jdoc.at("/value"_json_pointer).get(); + EXPECT_EQ(81.0, value); + gotTemperature = true; + }; + + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe( + "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" + "Temperature[z_motor_temp]"); + + m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|z_motor_temp|81"); + + ASSERT_TRUE(waitFor(5s, [&gotTemperature]() { return gotTemperature; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_LinearLoad) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + entity::JsonParser parser; + auto handler = make_unique(); + bool gotLinearLoad = false; + handler->m_receive = [&gotLinearLoad](std::shared_ptr, const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]", topic); + auto jdoc = json::parse(payload); + auto value = jdoc.at("/value"_json_pointer).get(); + EXPECT_EQ(50.0, value); + gotLinearLoad = true; + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]"); + + m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|Xload|50"); + ASSERT_TRUE(waitFor(5s, [&gotLinearLoad]() { return gotLinearLoad; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_DynamicCalibration) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool gotCalibration = false; + handler->m_receive = [this, &gotCalibration](std::shared_ptr, + const std::string &topic, + const std::string &payload) { + EXPECT_EQ( + "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]", + topic); + auto jdoc = json::parse(payload); + + auto value = jdoc.at("/value"_json_pointer); + ASSERT_TRUE(value.is_array()); + EXPECT_EQ(25, value.size()); + gotCalibration = true; + }; + + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + + m_client->subscribe( + "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]"); + + m_agentTestHelper->m_adapter->processData( + "2021-02-01T12:00:00Z|Xts|25|| 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 " + "5119 5119 5118 " + "5118 5117 5117 5119 5119 5118 5118 5118 5118 5118"); + + ASSERT_TRUE(waitFor(5s, [&gotCalibration]() { return gotCalibration; })); +} + +/// @test check if the condition includes the state as the key +TEST_F(MqttSinkTest, mqtt_should_publish_conditions_with_the_state_as_the_key) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + entity::JsonParser parser; + auto handler = make_unique(); + bool gotCondition = false; + + handler->m_receive = [&gotCondition](std::shared_ptr, const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature", topic); + auto jdoc = json::parse(payload); + EXPECT_EQ("Temperature is too high", jdoc.at("/Fault/value"_json_pointer).get()); + EXPECT_EQ("X111", jdoc.at("/Fault/nativeCode"_json_pointer).get()); + EXPECT_EQ("BAD", jdoc.at("/Fault/nativeSeverity"_json_pointer).get()); + EXPECT_EQ("HIGH", jdoc.at("/Fault/qualifier"_json_pointer).get()); + EXPECT_EQ("TEMPERATURE", jdoc.at("/Fault/type"_json_pointer).get()); + + gotCondition = true; + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + createAgent(); + + auto di = m_agentTestHelper->m_agent->getDataItemById("ctmp"); + ASSERT_TRUE(di); + ASSERT_EQ("000/Axes[Axes]/Rotary[C]/Condition/Temperature", di->getTopic()); + + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature"); + + m_agentTestHelper->m_adapter->processData( + "2018-04-27T05:00:26.555666|ctmp|fault|X111|BAD|HIGH|Temperature is too high"); + ASSERT_TRUE(waitFor(5s, [&gotCondition]() { return gotCondition; })); +} diff --git a/test_package/mqtt_sink_2_test.cpp b/test_package/mqtt_sink_2_test.cpp deleted file mode 100644 index bdae53427..000000000 --- a/test_package/mqtt_sink_2_test.cpp +++ /dev/null @@ -1,426 +0,0 @@ -// -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Ensure that gtest is the first header otherwise Windows raises an error -#include -// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) - -#include - -#include - -#include "agent_test_helper.hpp" -#include "json_helper.hpp" -#include "mtconnect/buffer/checkpoint.hpp" -#include "mtconnect/device_model/data_item/data_item.hpp" -#include "mtconnect/entity/entity.hpp" -#include "mtconnect/entity/json_parser.hpp" -#include "mtconnect/mqtt/mqtt_client_impl.hpp" -#include "mtconnect/mqtt/mqtt_server_impl.hpp" -#include "mtconnect/printer//json_printer.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt2_service.hpp" -#include "test_utilities.hpp" - -using namespace std; -using namespace mtconnect; -using namespace mtconnect::device_model::data_item; -using namespace mtconnect::sink::mqtt_sink; -using namespace mtconnect::asset; -using namespace mtconnect::configuration; - -// main -int main(int argc, char *argv[]) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - -using json = nlohmann::json; - -class MqttSink2Test : public testing::Test -{ -protected: - void SetUp() override - { - m_agentTestHelper = make_unique(); - m_jsonPrinter = std::make_unique(2, true); - } - - void TearDown() override - { - const auto agent = m_agentTestHelper->getAgent(); - if (agent) - { - m_agentTestHelper->getAgent()->stop(); - m_agentTestHelper->m_ioContext.run_for(100ms); - } - if (m_client) - { - m_client->stop(); - m_agentTestHelper->m_ioContext.run_for(500ms); - m_client.reset(); - } - if (m_server) - { - m_server->stop(); - m_agentTestHelper->m_ioContext.run_for(500ms); - m_server.reset(); - } - m_agentTestHelper.reset(); - m_jsonPrinter.reset(); - } - - void createAgent(std::string testFile = {}, ConfigOptions options = {}) - { - if (testFile == "") - testFile = "/samples/test_config.xml"; - - ConfigOptions opts(options); - MergeOptions(opts, {{"Mqtt2Sink", true}, - {configuration::MqttPort, m_port}, - {MqttCurrentInterval, 200ms}, - {MqttSampleInterval, 100ms}, - {configuration::MqttHost, "127.0.0.1"s}}); - m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.0", 25, false, true, opts); - addAdapter(); - - m_agentTestHelper->getAgent()->start(); - } - - void createServer(const ConfigOptions &options) - { - using namespace mtconnect::configuration; - ConfigOptions opts(options); - MergeOptions(opts, {{ServerIp, "127.0.0.1"s}, - {MqttPort, 0}, - {MqttTls, false}, - {AutoAvailable, false}, - {RealTime, false}}); - - m_server = - make_shared(m_agentTestHelper->m_ioContext, opts); - } - - template - bool waitFor(const chrono::duration &time, function pred) - { - boost::asio::steady_timer timer(m_agentTestHelper->m_ioContext); - timer.expires_after(time); - bool timeout = false; - timer.async_wait([&timeout](boost::system::error_code ec) { - if (!ec) - { - timeout = true; - } - }); - - while (!timeout && !pred()) - { - m_agentTestHelper->m_ioContext.run_for(100ms); - } - timer.cancel(); - - return pred(); - } - - void startServer() - { - if (m_server) - { - bool start = m_server->start(); - if (start) - { - m_port = m_server->getPort(); - m_agentTestHelper->m_ioContext.run_for(500ms); - } - } - } - - void createClient(const ConfigOptions &options, unique_ptr &&handler) - { - ConfigOptions opts(options); - MergeOptions(opts, {{MqttHost, "127.0.0.1"s}, - {MqttPort, m_port}, - {MqttTls, false}, - {AutoAvailable, false}, - {RealTime, false}}); - m_client = make_shared(m_agentTestHelper->m_ioContext, - opts, std::move(handler)); - } - - bool startClient() - { - bool started = m_client && m_client->start(); - if (started) - { - return waitFor(1s, [this]() { return m_client->isConnected(); }); - } - return started; - } - - void addAdapter(ConfigOptions options = ConfigOptions {}) - { - m_agentTestHelper->addAdapter(options, "localhost", 0, - m_agentTestHelper->m_agent->getDefaultDevice()->getName()); - } - - std::unique_ptr m_jsonPrinter; - std::shared_ptr m_server; - std::shared_ptr m_client; - std::unique_ptr m_agentTestHelper; - uint16_t m_port {0}; -}; - -TEST_F(MqttSink2Test, mqtt_sink_flat_formatt_check) -{ - ConfigOptions options {{MqttMaxTopicDepth, 9}, {ProbeTopic, "Device/F/l/a/t/F/o/r/m/a/t"s}}; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent("", options); - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(10s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotDevice = false; - handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Probe/000", topic); - - ErrorList list; - auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); - EXPECT_EQ(0, list.size()); - auto dev = dynamic_pointer_cast(ptr); - EXPECT_TRUE(dev); - EXPECT_EQ("LinuxCNC", dev->getComponentName()); - EXPECT_EQ("000", *dev->getUuid()); - - gotDevice = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Probe/000"); - - createAgent(); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - - ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Sample) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotSample = false; - handler->m_receive = [&gotSample](std::shared_ptr client, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Sample/000", topic); - - auto jdoc = json::parse(payload); - auto streams = jdoc.at("/MTConnectStreams/Streams/0/DeviceStream"_json_pointer); - EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); - - gotSample = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Sample/000"); - - createAgent(); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - ASSERT_FALSE(gotSample); - - m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); - ASSERT_TRUE(waitFor(10s, [&gotSample]() { return gotSample; })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Current) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotCurrent = false; - handler->m_receive = [&gotCurrent](std::shared_ptr client, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Current/000", topic); - - auto jdoc = json::parse(payload); - auto streams = jdoc.at("/MTConnectStreams/Streams/0/DeviceStream"_json_pointer); - EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); - - gotCurrent = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Current/000"); - - createAgent(); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - ASSERT_TRUE(gotCurrent); - - gotCurrent = false; - ASSERT_TRUE(waitFor(1s, [&gotCurrent]() { return gotCurrent; })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_with_uuid_first) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotDevice = false; - handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/000/Probe", topic); - - ErrorList list; - auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); - EXPECT_EQ(0, list.size()); - auto dev = dynamic_pointer_cast(ptr); - EXPECT_TRUE(dev); - EXPECT_EQ("LinuxCNC", dev->getComponentName()); - EXPECT_EQ("000", *dev->getUuid()); - - gotDevice = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/000/Probe"); - - createAgent("", {{configuration::ProbeTopic, "MTConnect/[device]/Probe"s}}); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - - ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_no_device_in_format) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotDevice = false; - handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Probe/000", topic); - - ErrorList list; - auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); - EXPECT_EQ(0, list.size()); - auto dev = dynamic_pointer_cast(ptr); - EXPECT_TRUE(dev); - EXPECT_EQ("LinuxCNC", dev->getComponentName()); - EXPECT_EQ("000", *dev->getUuid()); - - gotDevice = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Probe/000"); - - createAgent("", {{configuration::ProbeTopic, "MTConnect/Probe"s}}); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - - ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_agent_device) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - DevicePtr ad; - string agent_topic; - - auto handler = make_unique(); - bool gotDevice = false; - handler->m_receive = [&gotDevice, &parser, &agent_topic, &ad](std::shared_ptr client, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ(agent_topic, topic); - gotDevice = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent(); - - ad = m_agentTestHelper->m_agent->getAgentDevice(); - agent_topic = "MTConnect/Probe/Agent_"s + *ad->getUuid(); - m_client->subscribe(agent_topic); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - - ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); -} diff --git a/test_package/mqtt_sink_test.cpp b/test_package/mqtt_sink_test.cpp index 6675811f3..5aa93846b 100644 --- a/test_package/mqtt_sink_test.cpp +++ b/test_package/mqtt_sink_test.cpp @@ -14,10 +14,6 @@ // See the License for the specific language governing permissions and // limitations under the License. // - -/// @file -/// Test MQTT 1 Service - // Ensure that gtest is the first header otherwise Windows raises an error #include // Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) @@ -27,6 +23,7 @@ #include #include "agent_test_helper.hpp" +#include "json_helper.hpp" #include "mtconnect/buffer/checkpoint.hpp" #include "mtconnect/device_model/data_item/data_item.hpp" #include "mtconnect/entity/entity.hpp" @@ -35,6 +32,7 @@ #include "mtconnect/mqtt/mqtt_server_impl.hpp" #include "mtconnect/printer//json_printer.hpp" #include "mtconnect/sink/mqtt_sink/mqtt_service.hpp" +#include "test_utilities.hpp" using namespace std; using namespace mtconnect; @@ -52,7 +50,7 @@ int main(int argc, char *argv[]) using json = nlohmann::json; -class MqttSinkTest : public testing::Test +class MqttSink2Test : public testing::Test { protected: void SetUp() override @@ -72,7 +70,7 @@ class MqttSinkTest : public testing::Test if (m_client) { m_client->stop(); - m_agentTestHelper->m_ioContext.run_for(100ms); + m_agentTestHelper->m_ioContext.run_for(500ms); m_client.reset(); } if (m_server) @@ -93,8 +91,10 @@ class MqttSinkTest : public testing::Test ConfigOptions opts(options); MergeOptions(opts, {{"MqttSink", true}, {configuration::MqttPort, m_port}, + {MqttCurrentInterval, 200ms}, + {MqttSampleInterval, 100ms}, {configuration::MqttHost, "127.0.0.1"s}}); - m_agentTestHelper->createAgent(testFile, 8, 4, "2.0", 25, false, true, opts); + m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.0", 25, false, true, opts); addAdapter(); m_agentTestHelper->getAgent()->start(); @@ -118,7 +118,7 @@ class MqttSinkTest : public testing::Test bool waitFor(const chrono::duration &time, function pred) { boost::asio::steady_timer timer(m_agentTestHelper->m_ioContext); - timer.expires_from_now(time); + timer.expires_after(time); bool timeout = false; timer.async_wait([&timeout](boost::system::error_code ec) { if (!ec) @@ -166,7 +166,7 @@ class MqttSinkTest : public testing::Test bool started = m_client && m_client->start(); if (started) { - return waitFor(5s, [this]() { return m_client->isConnected(); }); + return waitFor(1s, [this]() { return m_client->isConnected(); }); } return started; } @@ -180,36 +180,13 @@ class MqttSinkTest : public testing::Test std::unique_ptr m_jsonPrinter; std::shared_ptr m_server; std::shared_ptr m_client; - std::shared_ptr m_service; std::unique_ptr m_agentTestHelper; uint16_t m_port {0}; }; -TEST_F(MqttSinkTest, mqtt_sink_should_be_loaded_by_agent) -{ - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - - ASSERT_TRUE(service); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker) +TEST_F(MqttSink2Test, mqtt_sink_flat_formatt_check) { - ConfigOptions options; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_with_UserNameandPassword) -{ - ConfigOptions options {{MqttUserName, "MQTT-SINK"s}, {MqttPassword, "mtconnect"s}}; + ConfigOptions options {{MqttMaxTopicDepth, 9}, {ProbeTopic, "Device/F/l/a/t/F/o/r/m/a/t"s}}; createServer(options); startServer(); @@ -218,24 +195,10 @@ TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_with_UserNameandPassword createAgent("", options); auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_without_UserNameandPassword) -{ - ConfigOptions options; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + ASSERT_TRUE(waitFor(10s, [&service]() { return service->isConnected(); })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_device) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe) { ConfigOptions options; createServer(options); @@ -248,7 +211,7 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_device) bool gotDevice = false; handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Device/000", topic); + EXPECT_EQ("MTConnect/Probe/000", topic); ErrorList list; auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); @@ -263,18 +226,18 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_device) createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Device/000"); + m_client->subscribe("MTConnect/Probe/000"); createAgent(); auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - ASSERT_TRUE(waitFor(5s, [&gotDevice]() { return gotDevice; })); + ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Streams) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_Sample) { ConfigOptions options; createServer(options); @@ -284,64 +247,34 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Streams) entity::JsonParser parser; auto handler = make_unique(); - bool foundLineDataItem = false; - handler->m_receive = [&foundLineDataItem](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]", topic); + bool gotSample = false; + handler->m_receive = [&gotSample](std::shared_ptr client, const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Sample/000", topic); auto jdoc = json::parse(payload); - string value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ("204", value); - foundLineDataItem = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); + auto streams = jdoc.at("/MTConnectStreams/Streams/0/DeviceStream"_json_pointer); + EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - - m_client->subscribe("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]"); - m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); - - ASSERT_TRUE(waitFor(5s, [&foundLineDataItem]() { return foundLineDataItem; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Asset) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Asset/0001", topic); - auto jdoc = json::parse(payload); - string id = jdoc.at("/Part/assetId"_json_pointer).get(); - EXPECT_EQ("0001", id); - gotControllerDataItem = true; + gotSample = true; }; + createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); + m_client->subscribe("MTConnect/Sample/000"); createAgent(); + auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Asset/0001"); - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|@ASSET@|@1|Part|TEST 1"); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); + ASSERT_FALSE(gotSample); - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); + m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); + ASSERT_TRUE(waitFor(10s, [&gotSample]() { return gotSample; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_RotaryMode) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_Current) { ConfigOptions options; createServer(options); @@ -351,135 +284,34 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_RotaryMode) entity::JsonParser parser; auto handler = make_unique(); - bool gotRotaryMode = false; - handler->m_receive = [&gotRotaryMode](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]", - topic); + bool gotCurrent = false; + handler->m_receive = [&gotCurrent](std::shared_ptr client, const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Current/000", topic); + auto jdoc = json::parse(payload); + auto streams = jdoc.at("/MTConnectStreams/Streams/0/DeviceStream"_json_pointer); + EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); - double v = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(5000.0, v); - gotRotaryMode = true; + gotCurrent = true; }; createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); + m_client->subscribe("MTConnect/Current/000"); createAgent(); - auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]"); - - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|block|G01X00|Sspeed|5000|line|204"); - - ASSERT_TRUE(waitFor(5s, [&gotRotaryMode]() { return gotRotaryMode; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Dataset) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]", - topic); - auto jdoc = json::parse(payload); - auto id = jdoc.at("/value/a"_json_pointer).get(); - EXPECT_EQ(1, id); - gotControllerDataItem = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent("/samples/data_set.xml"); - auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]"); - - m_agentTestHelper->m_adapter->processData("TIME|vars|a=1 b=2 c=3"); - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); -} -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Table) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/WorkOffsetTable[wpo]", - topic); - auto jdoc = json::parse(payload); - - auto jValue = jdoc.at("/value"_json_pointer); - int count = 0; - if (jValue.is_object()) - { - for (auto &[key, value] : jValue.items()) - { - if (key == "G53.1" || key == "G53.2" || key == "G53.3") - { - for (auto &[subKey, subValue] : value.items()) - { - if (key == "G53.1" && ((subKey == "X" && subValue.get() == 1) || - (subKey == "Y" && subValue.get() == 2) || - (subKey == "Z" && subValue.get() == 3))) - { - count++; - } - else if (key == "G53.2" && ((subKey == "X" && subValue.get() == 4) || - (subKey == "Y" && subValue.get() == 5) || - (subKey == "Z" && subValue.get() == 6))) - { - count++; - } - else if (key == "G53.3" && ((subKey == "X" && subValue.get() == 7.0) || - (subKey == "Y" && subValue.get() == 8.0) || - (subKey == "Z" && subValue.get() == 9.0) || - (subKey == "U" && subValue.get() == 10.0))) - { - count++; - } - } - } - } - EXPECT_EQ(10, count); - gotControllerDataItem = true; - } - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent("/samples/data_set.xml"); auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/" - "WorkOffsetTable[wpo]"); - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|wpo|G53.1={X=1.0 Y=2.0 Z=3.0} G53.2={X=4.0 Y=5.0 Z=6.0}" - "G53.3={X=7.0 Y=8.0 Z=9 U=10.0}"); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); + ASSERT_TRUE(gotCurrent); - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); + gotCurrent = false; + ASSERT_TRUE(waitFor(1s, [&gotCurrent]() { return gotCurrent; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Temperature) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_with_uuid_first) { ConfigOptions options; createServer(options); @@ -489,64 +321,36 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Temperature) entity::JsonParser parser; auto handler = make_unique(); - bool gotTemperature = false; - handler->m_receive = [&gotTemperature](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" - "Temperature[z_motor_temp]", - topic); - auto jdoc = json::parse(payload); + bool gotDevice = false; + handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, + const std::string &topic, const std::string &payload) { + EXPECT_EQ("MTConnect/000/Probe", topic); + + ErrorList list; + auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); + EXPECT_EQ(0, list.size()); + auto dev = dynamic_pointer_cast(ptr); + EXPECT_TRUE(dev); + EXPECT_EQ("LinuxCNC", dev->getComponentName()); + EXPECT_EQ("000", *dev->getUuid()); - auto value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(81.0, value); - gotTemperature = true; + gotDevice = true; }; createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); + m_client->subscribe("MTConnect/000/Probe"); - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" - "Temperature[z_motor_temp]"); - - m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|z_motor_temp|81"); - - ASSERT_TRUE(waitFor(5s, [&gotTemperature]() { return gotTemperature; })); -} + createAgent("", {{configuration::ProbeTopic, "MTConnect/[device]/Probe"s}}); -TEST_F(MqttSinkTest, mqtt_sink_should_publish_LinearLoad) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotLinearLoad = false; - handler->m_receive = [&gotLinearLoad](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]", topic); - auto jdoc = json::parse(payload); - auto value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(50.0, value); - gotLinearLoad = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent(); auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]"); - m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|Xload|50"); - ASSERT_TRUE(waitFor(5s, [&gotLinearLoad]() { return gotLinearLoad; })); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); + + ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_DynamicCalibration) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_no_device_in_format) { ConfigOptions options; createServer(options); @@ -556,75 +360,67 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_DynamicCalibration) entity::JsonParser parser; auto handler = make_unique(); - bool gotCalibration = false; - handler->m_receive = [this, &gotCalibration](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]", - topic); - auto jdoc = json::parse(payload); + bool gotDevice = false; + handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, + const std::string &topic, const std::string &payload) { + EXPECT_EQ("MTConnect/Probe/000", topic); - auto value = jdoc.at("/value"_json_pointer); - ASSERT_TRUE(value.is_array()); - EXPECT_EQ(25, value.size()); - gotCalibration = true; + ErrorList list; + auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); + EXPECT_EQ(0, list.size()); + auto dev = dynamic_pointer_cast(ptr); + EXPECT_TRUE(dev); + EXPECT_EQ("LinuxCNC", dev->getComponentName()); + EXPECT_EQ("000", *dev->getUuid()); + + gotDevice = true; }; createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); + m_client->subscribe("MTConnect/Probe/000"); - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + createAgent("", {{configuration::ProbeTopic, "MTConnect/Probe"s}}); - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]"); + auto service = m_agentTestHelper->getMqttService(); - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|Xts|25|| 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 " - "5119 5119 5118 " - "5118 5117 5117 5119 5119 5118 5118 5118 5118 5118"); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - ASSERT_TRUE(waitFor(5s, [&gotCalibration]() { return gotCalibration; })); + ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -/// @test check if the condition includes the state as the key -TEST_F(MqttSinkTest, mqtt_should_publish_conditions_with_the_state_as_the_key) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_agent_device) { ConfigOptions options; createServer(options); startServer(); ASSERT_NE(0, m_port); + entity::JsonParser parser; - auto handler = make_unique(); - bool gotCondition = false; - handler->m_receive = [&gotCondition](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature", topic); - auto jdoc = json::parse(payload); - EXPECT_EQ("Temperature is too high", jdoc.at("/Fault/value"_json_pointer).get()); - EXPECT_EQ("X111", jdoc.at("/Fault/nativeCode"_json_pointer).get()); - EXPECT_EQ("BAD", jdoc.at("/Fault/nativeSeverity"_json_pointer).get()); - EXPECT_EQ("HIGH", jdoc.at("/Fault/qualifier"_json_pointer).get()); - EXPECT_EQ("TEMPERATURE", jdoc.at("/Fault/type"_json_pointer).get()); + DevicePtr ad; + string agent_topic; - gotCondition = true; + auto handler = make_unique(); + bool gotDevice = false; + handler->m_receive = [&gotDevice, &parser, &agent_topic, &ad](std::shared_ptr client, + const std::string &topic, + const std::string &payload) { + EXPECT_EQ(agent_topic, topic); + gotDevice = true; }; + createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); createAgent(); - auto di = m_agentTestHelper->m_agent->getDataItemById("ctmp"); - ASSERT_TRUE(di); - ASSERT_EQ("000/Axes[Axes]/Rotary[C]/Condition/Temperature", di->getTopic()); + ad = m_agentTestHelper->m_agent->getAgentDevice(); + agent_topic = "MTConnect/Probe/Agent_"s + *ad->getUuid(); + m_client->subscribe(agent_topic); auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature"); - m_agentTestHelper->m_adapter->processData( - "2018-04-27T05:00:26.555666|ctmp|fault|X111|BAD|HIGH|Temperature is too high"); - ASSERT_TRUE(waitFor(5s, [&gotCondition]() { return gotCondition; })); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); + + ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } From 4e8f8fd41d4c121e4b2c8765be217d80acdab796 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 22:14:49 -0400 Subject: [PATCH 031/128] fixed cancel --- src/mtconnect/observation/change_observer.cpp | 3 ++- src/mtconnect/observation/change_observer.hpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 25 ++++++++++++++----- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index e186a592b..a2c8a1516 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -47,7 +47,8 @@ namespace mtconnect::observation { void ChangeObserver::handler(boost::system::error_code ec) { - boost::asio::post(m_strand, boost::bind(m_handler, ec)); + if (m_handler) + boost::asio::post(m_strand, boost::bind(m_handler, ec)); } // Signaler Management diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index b38cc6161..4591e0828 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -147,9 +147,9 @@ namespace mtconnect::observation { void clear() { std::unique_lock lock(m_mutex); + m_timer.cancel(); m_signalers.clear(); m_handler.clear(); - m_timer.cancel(); } private: diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 48905e154..2c870ca23 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -116,7 +116,7 @@ namespace mtconnect { {"format", QUERY, "The format of the response document: 'xml' or 'json'"}, {"heartbeat", QUERY, "Time in ms between publishing a empty document when no data has changed"}, - {"requestId", PATH, "webservice request id"}}); + {"id", PATH, "webservice request id"}}); createProbeRoutings(); createCurrentRoutings(); @@ -762,8 +762,21 @@ namespace mtconnect { }; auto cancelHandler = [&](SessionPtr session, RequestPtr request) -> bool { - auto requestId = *request->parameter("requestId"); - return session->cancelRequest(requestId); + if (request->m_requestId) + { + auto requestId = *request->m_requestId; + auto success = session->cancelRequest(requestId); + auto response = make_unique( + status::ok, "{ \"success\": \""s + (success ? "true" : "false") + "\"}", + "application/json"); + + respond(session, std::move(response), request->m_requestId); + return true; + } + else + { + return false; + } }; string qp( @@ -783,9 +796,9 @@ namespace mtconnect { "optionally filtered by the `path` and starting at `from`. By default, from is " "the first available observation known to the agent") .command("sample"); - m_server - ->addRouting({boost::beast::http::verb::get, "/cancel/requestId={string}", cancelHandler}) - .document("MTConnect WebServices Cancel Stream", "Cancels a streaming sample request"); + m_server->addRouting({boost::beast::http::verb::get, "/cancel/id={string}", cancelHandler}) + .document("MTConnect WebServices Cancel Stream", "Cancels a streaming sample request") + .command("cancel"); } void RestService::createPutObservationRoutings() From 350a031a4bcdc64a8fc8fa3ae33694d471e54a76 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 22:59:06 -0400 Subject: [PATCH 032/128] refactored async observer and created abstract async response to cancel timed responses --- src/mtconnect/observation/change_observer.cpp | 2 +- src/mtconnect/observation/change_observer.hpp | 46 ++++++++++++------- src/mtconnect/sink/rest_sink/rest_service.cpp | 33 ++++++++----- src/mtconnect/sink/rest_sink/session.hpp | 4 +- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index a2c8a1516..b15a646e9 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -100,7 +100,7 @@ namespace mtconnect::observation { buffer::CircularBuffer &buffer, FilterSet &&filter, std::chrono::milliseconds interval, std::chrono::milliseconds heartbeat) - : m_interval(interval), + : AsyncResponse(interval), m_heartbeat(heartbeat), m_last(std::chrono::system_clock::now()), m_filter(std::move(filter)), diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index 4591e0828..e3f5bc40b 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -194,6 +194,32 @@ namespace mtconnect::observation { std::list m_observers; }; + /// @brief Abstract class for things asynchronouos timers + class AGENT_LIB_API AsyncResponse : public std::enable_shared_from_this + { + public: + AsyncResponse(std::chrono::milliseconds interval) : m_interval(interval) {} + + virtual bool cancel() = 0; + + /// @brief method to determine if the sink is running + virtual bool isRunning() = 0; + + /// @brief get the request id for webservices + const auto &getRequestId() const { return m_requestId; } + + /// @brief sets the optonal request id for webservices. + void setRequestId(const std::optional &id) { m_requestId = id; } + + /// @brief Get the interval + const auto &getInterval() const { return m_interval; } + + protected: + std::chrono::milliseconds m_interval { + 0}; //! the minimum amout of time to wait before calling the handler + std::optional m_requestId; //! request id + }; + /// @brief Asyncronous change context for waiting for changes /// /// This class must be subclassed and provide a fail and isRunning method. @@ -205,7 +231,7 @@ namespace mtconnect::observation { /// /// The handler and sequence numbers are handled inside the circular buffer lock to prevent race /// conditions with incoming data. - class AGENT_LIB_API AsyncObserver : public std::enable_shared_from_this + class AGENT_LIB_API AsyncObserver : public AsyncResponse { public: /// @Brief callback when observations are ready @@ -226,7 +252,7 @@ namespace mtconnect::observation { virtual ~AsyncObserver() = default; /// @brief Get a shared pointed - auto getptr() const { return const_cast(this)->shared_from_this(); } + auto getptr() { return std::dynamic_pointer_cast(shared_from_this()); } /// @brief sets up the `ChangeObserver` using the filter and initializes the references to the /// buffer @@ -244,11 +270,8 @@ namespace mtconnect::observation { /// @brief abstract call to failure handler virtual void fail(boost::beast::http::status status, const std::string &message) = 0; - /// @brief method to determine if the sink is running - virtual bool isRunning() = 0; - /// @brief Stop all timers and release resources. - virtual bool cancel() + bool cancel() override { m_observer.clear(); return true; @@ -266,14 +289,6 @@ namespace mtconnect::observation { auto getSequence() const { return m_sequence; } auto isEndOfBuffer() const { return m_endOfBuffer; } const auto &getFilter() const { return m_filter; } - const auto &getRequestId() const { return m_requestId; } - ///@} - - ///@{ - /// @name setters - - /// @brief sets the optonal request id for webservices. - void setRequestId(const std::optional &id) { m_requestId = id; } ///@} mutable bool m_endOfBuffer {false}; //! Public indicator that we are at the end of the buffer @@ -288,8 +303,6 @@ namespace mtconnect::observation { protected: SequenceNumber_t m_sequence {0}; //! the current sequence number - std::chrono::milliseconds m_interval { - 0}; //! the minimum amout of time to wait before calling the handler std::chrono::milliseconds m_heartbeat { 0}; //! the maximum amount of time to wait before sending a heartbeat std::chrono::system_clock::time_point m_last; //! the last time the handler completed @@ -298,6 +311,5 @@ namespace mtconnect::observation { ChangeObserver m_observer; //! the change observer mtconnect::buffer::CircularBuffer &m_buffer; //! reference to the circular buffer - std::optional m_requestId; //! request id }; } // namespace mtconnect::observation diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 2c870ca23..94d413236 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -1119,20 +1119,30 @@ namespace mtconnect { return 0; } - struct AsyncCurrentResponse + struct AsyncCurrentResponse : public AsyncResponse { - AsyncCurrentResponse(rest_sink::SessionPtr session, asio::io_context &context) - : m_session(session), m_timer(context) + AsyncCurrentResponse(rest_sink::SessionPtr session, asio::io_context &context, + chrono::milliseconds interval) + : AsyncResponse(interval), m_session(session), m_timer(context) {} + auto getptr() { return dynamic_pointer_cast(shared_from_this()); } + + bool cancel() override + { + m_timer.cancel(); + m_session.reset(); + return true; + } + + bool isRunning() override { return (bool)m_session; } + std::weak_ptr m_service; rest_sink::SessionPtr m_session; - chrono::milliseconds m_interval; const Printer *m_printer {nullptr}; FilterSetOpt m_filter; boost::asio::steady_timer m_timer; bool m_pretty {false}; - std::optional m_requestId; }; void RestService::streamCurrentRequest(SessionPtr session, const Printer *printer, @@ -1149,17 +1159,18 @@ namespace mtconnect { dev = checkDevice(printer, *device); } - auto asyncResponse = make_shared(session, m_context); + auto asyncResponse = + make_shared(session, m_context, chrono::milliseconds {interval}); if (path || device || deviceType) { asyncResponse->m_filter = make_optional(); checkPath(printer, path, dev, *asyncResponse->m_filter, deviceType); } - asyncResponse->m_interval = chrono::milliseconds {interval}; asyncResponse->m_printer = printer; asyncResponse->m_service = getptr(); asyncResponse->m_pretty = pretty; - asyncResponse->m_requestId = requestId; + asyncResponse->setRequestId(requestId); + session->addObserver(asyncResponse); asyncResponse->m_session->beginStreaming( printer->mimeType(), @@ -1202,16 +1213,16 @@ namespace mtconnect { asyncResponse->m_session->writeChunk( fetchCurrentData(asyncResponse->m_printer, asyncResponse->m_filter, nullopt, - asyncResponse->m_pretty, asyncResponse->m_requestId), + asyncResponse->m_pretty, asyncResponse->getRequestId()), boost::asio::bind_executor( m_strand, [this, asyncResponse]() { - asyncResponse->m_timer.expires_from_now(asyncResponse->m_interval); + asyncResponse->m_timer.expires_from_now(asyncResponse->getInterval()); asyncResponse->m_timer.async_wait(boost::asio::bind_executor( m_strand, boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); }), - asyncResponse->m_requestId); + asyncResponse->getRequestId()); } catch (RequestError &re) { diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index ba690894f..c49a26586 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -120,7 +120,7 @@ namespace mtconnect::sink::rest_sink { } /// @brief Add an observer to the list for cleanup later. - void addObserver(std::weak_ptr observer) + void addObserver(std::weak_ptr observer) { m_observers.push_back(observer); } @@ -148,7 +148,7 @@ namespace mtconnect::sink::rest_sink { bool m_allowPuts {false}; std::set m_allowPutsFrom; boost::asio::ip::tcp::endpoint m_remote; - std::list> m_observers; + std::list> m_observers; }; } // namespace mtconnect::sink::rest_sink From 2e324a059bd413cd070f5da2bc6f32180dcf24e7 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 25 Apr 2024 12:57:02 -0400 Subject: [PATCH 033/128] Fixed race in change observer destructor. --- src/mtconnect/observation/change_observer.cpp | 11 +++ src/mtconnect/observation/change_observer.hpp | 8 +-- src/mtconnect/sink/rest_sink/rest_service.cpp | 71 +++++++++++-------- 3 files changed, 55 insertions(+), 35 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index b15a646e9..e106bb62e 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -29,14 +29,25 @@ using namespace std; namespace mtconnect::observation { ChangeObserver::~ChangeObserver() { + std::lock_guard scopedLock(m_mutex); + clear(); + } + + void ChangeObserver::clear() + { + std::unique_lock lock(m_mutex); + m_timer.cancel(); + m_handler.clear(); for (const auto signaler : m_signalers) signaler->removeObserver(this); + m_signalers.clear(); } void ChangeObserver::addSignaler(ChangeSignaler *sig) { m_signalers.emplace_back(sig); } bool ChangeObserver::removeSignaler(ChangeSignaler *sig) { + std::lock_guard scopedLock(m_mutex); auto newEndPos = std::remove(m_signalers.begin(), m_signalers.end(), sig); if (newEndPos == m_signalers.end()) return false; diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index e3f5bc40b..c274e848e 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -144,13 +144,7 @@ namespace mtconnect::observation { ///@} /// @brief clear the observer information. - void clear() - { - std::unique_lock lock(m_mutex); - m_timer.cancel(); - m_signalers.clear(); - m_handler.clear(); - } + void clear(); private: boost::asio::io_context::strand &m_strand; diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 94d413236..82c1df6cc 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -1090,12 +1090,14 @@ namespace mtconnect { if (m_logStreamData) asyncResponse->m_log << content << endl; - asyncResponse->m_session->writeChunk( - content, - asio::bind_executor(m_strand, - boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), - asyncResponse->getRequestId()); - + if (asyncResponse->m_session) + { + asyncResponse->m_session->writeChunk( + content, + asio::bind_executor(m_strand, + boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), + asyncResponse->getRequestId()); + } return end; } @@ -1103,9 +1105,12 @@ namespace mtconnect { { LOG(error) << asyncResponse->m_session->getRemote().address() << ": Error processing request: " << re.what(); - ResponsePtr resp = std::make_unique(re); - asyncResponse->m_session->writeResponse(std::move(resp)); - asyncResponse->m_session->close(); + if (asyncResponse->m_session) + { + ResponsePtr resp = std::make_unique(re); + asyncResponse->m_session->writeResponse(std::move(resp)); + asyncResponse->m_session->close(); + } } catch (...) @@ -1194,7 +1199,7 @@ namespace mtconnect { if (!service || !m_server || !m_server->isRunning()) { LOG(warning) << "Trying to send chunk when service has stopped"; - if (service) + if (service && asyncResponse->m_session) { asyncResponse->m_session->fail(boost::beast::http::status::internal_server_error, "Agent shutting down, aborting stream"); @@ -1206,31 +1211,38 @@ namespace mtconnect { { LOG(warning) << "Unexpected error streamNextCurrent, aborting"; LOG(warning) << ec.category().message(ec.value()) << ": " << ec.message(); - asyncResponse->m_session->fail(boost::beast::http::status::internal_server_error, - "Unexpected error streamNextCurrent, aborting"); + if (asyncResponse->m_session) + asyncResponse->m_session->fail(boost::beast::http::status::internal_server_error, + "Unexpected error streamNextCurrent, aborting"); return; } - asyncResponse->m_session->writeChunk( - fetchCurrentData(asyncResponse->m_printer, asyncResponse->m_filter, nullopt, - asyncResponse->m_pretty, asyncResponse->getRequestId()), - boost::asio::bind_executor( - m_strand, - [this, asyncResponse]() { - asyncResponse->m_timer.expires_from_now(asyncResponse->getInterval()); - asyncResponse->m_timer.async_wait(boost::asio::bind_executor( - m_strand, - boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); - }), - asyncResponse->getRequestId()); + if (asyncResponse->m_session) + { + asyncResponse->m_session->writeChunk( + fetchCurrentData(asyncResponse->m_printer, asyncResponse->m_filter, nullopt, + asyncResponse->m_pretty, asyncResponse->getRequestId()), + boost::asio::bind_executor( + m_strand, + [this, asyncResponse]() { + asyncResponse->m_timer.expires_from_now(asyncResponse->getInterval()); + asyncResponse->m_timer.async_wait(boost::asio::bind_executor( + m_strand, + boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); + }), + asyncResponse->getRequestId()); + } } catch (RequestError &re) { LOG(error) << asyncResponse->m_session->getRemote().address() << ": Error processing request: " << re.what(); - ResponsePtr resp = std::make_unique(re); - asyncResponse->m_session->writeResponse(std::move(resp)); - asyncResponse->m_session->close(); + if (asyncResponse->m_session) + { + ResponsePtr resp = std::make_unique(re); + asyncResponse->m_session->writeResponse(std::move(resp)); + asyncResponse->m_session->close(); + } } catch (...) @@ -1238,7 +1250,10 @@ namespace mtconnect { std::stringstream txt; txt << asyncResponse->m_session->getRemote().address() << ": Unknown Error thrown"; LOG(error) << txt.str(); - asyncResponse->m_session->fail(boost::beast::http::status::not_found, txt.str()); + if (asyncResponse->m_session) + { + asyncResponse->m_session->fail(boost::beast::http::status::not_found, txt.str()); + } } } From 8b24f2e94231814e07f1b1ba7f6a5290929b396f Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 27 Apr 2024 14:02:39 -0400 Subject: [PATCH 034/128] fixed requests in websockets --- src/mtconnect/observation/change_observer.cpp | 2 +- src/mtconnect/sink/rest_sink/request.hpp | 3 + .../sink/rest_sink/websocket_session.hpp | 57 ++++++++++--------- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index e106bb62e..f489b287c 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -32,7 +32,7 @@ namespace mtconnect::observation { std::lock_guard scopedLock(m_mutex); clear(); } - + void ChangeObserver::clear() { std::unique_lock lock(m_mutex); diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index ac3f2c33b..40eb12172 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -57,6 +57,9 @@ namespace mtconnect::sink::rest_sink { /// The request can be a simple reply response or streaming request struct Request { + Request() = default; + Request(const Request &request) = default; + boost::beast::http::verb m_verb; ///< GET, PUT, POST, or DELETE std::string m_body; ///< The body of the request std::string m_accepts; ///< The accepts header diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index f06b916c8..013d86016 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -42,6 +42,7 @@ namespace mtconnect::sink::rest_sink { std::optional m_streamBuffer; Complete m_complete; bool m_streaming {false}; + RequestPtr m_request; }; /// @brief A websocket session that provides a pubsub interface using REST parameters @@ -342,7 +343,10 @@ namespace mtconnect::sink::rest_sink { { // Extract the parameters from the json doc to map them to the REST // protocol parameters - m_request->m_verb = beast::http::verb::get; + auto request = make_unique(*m_request); + + request->m_verb = beast::http::verb::get; + request->m_parameters.clear(); const auto &object = doc.GetObject(); for (auto &it : object) @@ -353,58 +357,56 @@ namespace mtconnect::sink::rest_sink { // Skip nulls break; case rapidjson::kFalseType: - m_request->m_parameters.emplace(make_pair(it.name.GetString(), false)); + request->m_parameters.emplace(make_pair(it.name.GetString(), false)); break; case rapidjson::kTrueType: - m_request->m_parameters.emplace(make_pair(it.name.GetString(), true)); + request->m_parameters.emplace(make_pair(it.name.GetString(), true)); break; case rapidjson::kObjectType: break; case rapidjson::kArrayType: break; case rapidjson::kStringType: - m_request->m_parameters.emplace( + request->m_parameters.emplace( make_pair(it.name.GetString(), string(it.value.GetString()))); break; case rapidjson::kNumberType: if (it.value.Is()) - m_request->m_parameters.emplace( - make_pair(it.name.GetString(), it.value.Get())); + request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace( + request->m_parameters.emplace( make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace( + request->m_parameters.emplace( make_pair(it.name.GetString(), (uint64_t)it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace( + request->m_parameters.emplace( make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace( + request->m_parameters.emplace( make_pair(it.name.GetString(), it.value.Get())); break; } } - if (m_request->m_parameters.count("request") > 0) + if (request->m_parameters.count("request") > 0) { - m_request->m_command = get(m_request->m_parameters["request"]); - m_request->m_parameters.erase("request"); + request->m_command = get(request->m_parameters["request"]); + request->m_parameters.erase("request"); } - if (m_request->m_parameters.count("id") > 0) + if (request->m_parameters.count("id") > 0) { - auto &v = m_request->m_parameters["id"]; + auto &v = request->m_parameters["id"]; string id = visit(overloaded {[](monostate m) { return ""s; }, [](auto v) { return boost::lexical_cast(v); }}, v); - m_request->m_requestId = id; - m_request->m_parameters.erase("id"); + request->m_requestId = id; + request->m_parameters.erase("id"); } - auto &id = *(m_request->m_requestId); - + auto &id = *(request->m_requestId); auto res = m_requests.emplace(id, id); if (!res.second) { @@ -412,14 +414,17 @@ namespace mtconnect::sink::rest_sink { boost::system::error_code ec; fail(status::bad_request, "Duplicate request Id", ec); } - - if (!m_dispatch(derived().shared_ptr(), m_request)) + else { - ostringstream txt; - txt << "Failed to find handler for " << buffer; - LOG(error) << txt.str(); - boost::system::error_code ec; - fail(status::bad_request, "Duplicate request Id", ec); + res.first->second.m_request = std::move(request); + if (!m_dispatch(derived().shared_ptr(), res.first->second.m_request)) + { + ostringstream txt; + txt << "Failed to find handler for " << buffer; + LOG(error) << txt.str(); + boost::system::error_code ec; + fail(status::bad_request, "Duplicate request Id", ec); + } } } From 538a9a693da06538d9e979850bba8fdee46ed350 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 17:21:40 -0400 Subject: [PATCH 035/128] use new uuid to check for device with * uuid shdr command --- src/mtconnect/source/adapter/shdr/shdr_adapter.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp b/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp index a96e27c53..366b4e9b1 100644 --- a/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp +++ b/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp @@ -227,9 +227,7 @@ namespace mtconnect::source::adapter::shdr { if (command == "uuid") { - DevicePtr dp; - if (auto dev = GetOption(m_options, configuration::Device); - dev && (dp = m_pipeline.getContext()->m_contract->findDevice(*dev))) + if (auto dp = m_pipeline.getContext()->m_contract->findDevice(value); dp) { if (!dp->preserveUuid()) { From d940959c0bb07118d3505255dcab68799a6c4f74 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 17:25:04 -0400 Subject: [PATCH 036/128] Version 2.3.0.6 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 81d1e1c71..f5560bb92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) set(AGENT_VERSION_BUILD 0) -set(AGENT_VERSION_RC "RC1") +set(AGENT_VERSION_RC "RC2") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) From 4d0ea091cf94c2aa879bc8938d2866fd74d28ba8 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 11 Apr 2024 18:32:59 -0400 Subject: [PATCH 037/128] Fixed port in url for MQTT service. --- src/mtconnect/mqtt/mqtt_client_impl.hpp | 1 + src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp | 9 ++------- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index 0a20377dd..5a3b4aafc 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -164,6 +164,7 @@ namespace mtconnect { m_connected = false; if (m_handler && m_handler->m_disconnected) m_handler->m_disconnected(shared_from_this()); + m_handler->m_disconnected(shared_from_this()); if (m_running) { reconnect(); diff --git a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp index 7765ef2fb..7c623082c 100644 --- a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp +++ b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp @@ -85,12 +85,7 @@ namespace mtconnect { { m_options[configuration::MqttHost] = m_options[configuration::Host]; } - if (!HasOption(m_options, configuration::MqttPort) && - HasOption(m_options, configuration::Port)) - { - m_options[configuration::MqttPort] = m_options[configuration::Port]; - } - else + if (!HasOption(m_options, configuration::MqttPort)) { m_options[configuration::MqttPort] = 1883; } @@ -139,7 +134,7 @@ namespace mtconnect { else { m_client = make_shared(m_ioContext, m_options, - move(clientHandler)); + std::move(clientHandler)); } m_identity = m_client->getIdentity(); From 2e09bb4ac41a8e993965dc24f4cd7d4eaca992fb Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 12 Apr 2024 09:52:41 -0400 Subject: [PATCH 038/128] fixed crash when closing mqtt client. set close handler to nullptr if already disconnected. --- src/mtconnect/mqtt/mqtt_client_impl.hpp | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index 5a3b4aafc..56eb701ce 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -236,6 +236,7 @@ namespace mtconnect { { client->async_disconnect(10s, [client, url](mqtt::error_code ec) { LOG(warning) << url << " disconnected: " << ec.message(); + client->set_close_handler(nullptr); }); client.reset(); @@ -412,6 +413,13 @@ namespace mtconnect { public: using base = MqttClientImpl; using base::base; + /// @brief Get a shared pointer to this + /// @return shared pointer to this + shared_ptr getptr() + { + return static_pointer_cast(shared_from_this()); + } + /// @brief Get the Mqtt TCP Client /// @return pointer to the Mqtt TCP Client auto &getClient() @@ -438,6 +446,12 @@ namespace mtconnect { public: using base = MqttClientImpl; using base::base; + /// @brief Get a shared pointer to this + /// @return shared pointer to this + shared_ptr getptr() + { + return static_pointer_cast(shared_from_this()); + } /// @brief Get the Mqtt TLS Client /// @return pointer to the Mqtt TLS Client @@ -481,6 +495,13 @@ namespace mtconnect { public: using base = MqttClientImpl; using base::base; + /// @brief Get a shared pointer to this + /// @return shared pointer to this + shared_ptr getptr() + { + return static_pointer_cast(shared_from_this()); + } + /// @brief Get the Mqtt TLS WebSocket Client /// @return pointer to the Mqtt TLS WebSocket Client auto &getClient() @@ -513,6 +534,13 @@ namespace mtconnect { public: using base = MqttClientImpl; using base::base; + /// @brief Get a shared pointer to this + /// @return shared pointer to this + shared_ptr getptr() + { + return static_pointer_cast(shared_from_this()); + } + /// @brief Get the Mqtt TLS WebSocket Client /// @return pointer to the Mqtt TLS WebSocket Client auto &getClient() From 1025b396590bf2be862ed56f184844fb4a5d259b Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sun, 28 Apr 2024 12:58:57 -0400 Subject: [PATCH 039/128] Added initial value handling --- src/mtconnect/agent.cpp | 18 +++++++++++++++ .../device_model/data_item/data_item.cpp | 7 +++++- .../device_model/data_item/data_item.hpp | 11 +++++---- test_package/agent_test.cpp | 23 +++++++++++++++++++ 4 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index b298501ee..864d7f1a4 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -290,6 +290,24 @@ namespace mtconnect { // --------------------------------------- void Agent::receiveObservation(observation::ObservationPtr observation) { + // Check for availability + if (observation->getDataItem()->getType() == "AVAILABILITY" && !observation->isUnavailable()) + { + // Set all the initial values. + auto device = observation->getDataItem()->getComponent()->getDevice(); + for (auto item : device->getDeviceDataItems()) + { + if (item.expired()) + continue; + + auto di = item.lock(); + if (di->hasInitialValue()) + { + m_loopback->receive(di, *di->getInitialValue()); + } + } + } + std::lock_guard lock(m_circularBuffer); if (m_circularBuffer.addToBuffer(observation) != 0) { diff --git a/src/mtconnect/device_model/data_item/data_item.cpp b/src/mtconnect/device_model/data_item/data_item.cpp index f65e22381..53f238b95 100644 --- a/src/mtconnect/device_model/data_item/data_item.cpp +++ b/src/mtconnect/device_model/data_item/data_item.cpp @@ -70,7 +70,7 @@ namespace mtconnect { {"Definition", ValueType::ENTITY, definition, false}, {"Constraints", ValueType::ENTITY_LIST, constraints, false}, {"Relationships", ValueType::ENTITY_LIST, relationships, false}, - {"InitialValue", ValueType::DOUBLE, false}, + {"InitialValue", ValueType::STRING, false}, {"ResetTrigger", false}}); factory->setFunction([](const std::string &name, Properties &props) -> EntityPtr { auto ptr = make_shared(name, props); @@ -201,6 +201,11 @@ namespace mtconnect { } } } + + if (const auto &init = maybeGet("InitialValue"); init) + { + m_initialValue = *init; + } if (const auto &filters = getList("Filters")) { diff --git a/src/mtconnect/device_model/data_item/data_item.hpp b/src/mtconnect/device_model/data_item/data_item.hpp index 1337cd748..7f62fdbd8 100644 --- a/src/mtconnect/device_model/data_item/data_item.hpp +++ b/src/mtconnect/device_model/data_item/data_item.hpp @@ -139,7 +139,11 @@ namespace mtconnect { /// @brief get the topic name leaf node for this data item /// @return the topic name const auto &getTopicName() const { return m_topicName; } - + + /// @brief get the initial value if one is set + /// @return optional initial value + const auto &getInitialValue() const { return m_initialValue; } + Category getCategory() const { return m_category; } Representation getRepresentation() const { return m_representation; } SpecialClass getSpecialClass() const { return m_specialClass; } @@ -169,6 +173,7 @@ namespace mtconnect { bool isDiscrete() const { return m_discrete; } bool isThreeSpace() const { return m_specialClass == THREE_SPACE_CLS; } bool isOrphan() const { return m_component.expired(); } + bool hasInitialValue() const { return bool(m_initialValue); } ///@} void makeDiscrete() @@ -279,6 +284,7 @@ namespace mtconnect { std::optional m_source; std::string m_preferredName; std::optional m_constantValue; + std::optional m_initialValue; std::optional m_minimumDelta; std::optional m_minimumPeriod; std::string m_key; @@ -301,9 +307,6 @@ namespace mtconnect { // The reset trigger; std::string m_resetTrigger; - // Initial value - std::string m_initialValue; - // Component that data item is associated with std::weak_ptr m_component; std::weak_ptr m_composition; diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 82bf2ba98..f3cabd50d 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -3138,3 +3138,26 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_fa ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); } } + + +TEST_F(AgentTest, should_initialize_observaton_to_initial_value_when_available) +{ + m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.2", 4, true); + + auto device = m_agentTestHelper->getAgent()->getDeviceByName("LinuxCNC"); + ASSERT_TRUE(device); + + addAdapter(); + + { + PARSE_XML_RESPONSE("/current"); + ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:PartCount", "UNAVAILABLE"); + } + + m_agentTestHelper->m_adapter->processData("2024-01-22T20:00:00Z|avail|AVAILABLE"); + + { + PARSE_XML_RESPONSE("/current"); + ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:PartCount", "0"); + } +} From e8e0fc0d91b99b21892142278ec18dab88e1e79d Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sun, 28 Apr 2024 13:10:33 -0400 Subject: [PATCH 040/128] use brew on mac to install conan 2 --- .github/workflows/build.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 263808dc0..e503cfb98 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -170,8 +170,9 @@ jobs: key: ${{ runner.os }}-build-${{ matrix.shared }}-${{ hashFiles('**/conanfile.py') }} - name: Install Conan - uses: turtlebrowser/get-conan@v1.2 - + run: | + brew install conan + - name: Setup Conan if: steps.cache.outputs.cache-hit != 'true' run: | From f59f4bc72cd1e4b868cfb3391275dbf694608d74 Mon Sep 17 00:00:00 2001 From: William Sobel Date: Sun, 28 Apr 2024 15:22:22 -0400 Subject: [PATCH 041/128] Fixed initial value. Changed to string. --- test_package/json_printer_probe_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_package/json_printer_probe_test.cpp b/test_package/json_printer_probe_test.cpp index b5544bc54..1760aea92 100644 --- a/test_package/json_printer_probe_test.cpp +++ b/test_package/json_printer_probe_test.cpp @@ -246,7 +246,7 @@ TEST_F(JsonPrinterProbeTest, InitialValue) json count = ::find(items, "/DataItem/id", "d2e9e4a0"); ASSERT_TRUE(count.is_object()); - ASSERT_EQ(1.0, count.at("/DataItem/InitialValue"_json_pointer).get()); + ASSERT_EQ("1", count.at("/DataItem/InitialValue"_json_pointer).get()); } TEST_F(JsonPrinterProbeTest, DataItemFilters) From afa411c66fc79b93068f36ad7e6acd49d8b2b66e Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sun, 28 Apr 2024 16:25:10 -0400 Subject: [PATCH 042/128] version 2.3.0.8 --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5560bb92..9cd4564cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,13 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) +<<<<<<< HEAD set(AGENT_VERSION_BUILD 0) set(AGENT_VERSION_RC "RC2") +======= +set(AGENT_VERSION_BUILD 8) +set(AGENT_VERSION_RC "") +>>>>>>> de28136e (version 2.3.0.8) # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) From 12da91e0e9ce84b2824a2562cd18b5c3561f98aa Mon Sep 17 00:00:00 2001 From: Johnathan Arsenault Date: Thu, 18 Apr 2024 13:23:20 -0400 Subject: [PATCH 043/128] generic ubuntu deb package creation on release and add it to the release in github --- .github/workflows/build.yml | 41 +++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e503cfb98..773cc7352 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -149,8 +149,45 @@ jobs: shell: bash run: | export CTEST_OUTPUT_ON_FAILURE=TRUE - conan create . --build=missing -pr conan/profiles/gcc -o shared=${{ matrix.shared }} -o with_docs=False - + conan create . --build=missing -pr conan/profiles/gcc -o shared=${{ matrix.shared }} -o with_docs=False -o cpack=True -o cpack_name=dist -o cpack_destination=${{ github.workspace }} + + - name: Cleanse package version + run: | + if [[ $PACKAGE_VERSION == v*.*.*.* ]]; then + echo "PACKAGE_VERSION=${PACKAGE_VERSION:1}"" >> $GITHUB_ENV + elif [[ $PACKAGE_VERSION == [0-9].*.*.* ]]; then + echo "PACKAGE_VERSION=${PACKAGE_VERSION:0}"" >> $GITHUB_ENV + else + echo "PACKAGE_VERSION=0.0.0.0" >> $GITHUB_ENV + fi + - name: Prepare Debian Package + shell: bash + working-directory: ${{ github.workspace }} + run: | + mkdir -p pkgroot/home/edge/ + ls -lah pkgroot + tar -xzf dist.tar.gz -C pkgroot/ + mv pkgroot/dist pkgroot/usr + - name: Create Debian Package + id: create_debian_package + uses: jiro4989/build-deb-action@v3 + with: + package: mtconnect-agent + package_root: ${{ github.workspace}}/pkgroot + version: ${{ env.PACKAGE_VERSION }} + arch: amd64 + desc: "MTConnect Agent for Ununtu" + maintainer: Datanomix + - name: Release + uses: softprops/action-gh-release@v1 + if: ${{ startsWith(github.ref, 'refs/tags/') && matrix.shared == 'False' }} + with: + name: Version ${{ github.ref_name }} + draft: true + files: | + ${{ github.workspace }}/${{ steps.create_debian_package.outputs.file_name }} + token: ${{ secrets.RELEASE_GITHUB_TOKEN }} + build_macos: runs-on: macos-latest name: "MacOS Latest, Shared: ${{ matrix.shared }}" From 8f23034e3c69a976140e618043ddfb8e5249b698 Mon Sep 17 00:00:00 2001 From: Johnathan Arsenault Date: Thu, 18 Apr 2024 14:31:22 -0400 Subject: [PATCH 044/128] remove extra quotes --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 773cc7352..c14e8f228 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -154,9 +154,9 @@ jobs: - name: Cleanse package version run: | if [[ $PACKAGE_VERSION == v*.*.*.* ]]; then - echo "PACKAGE_VERSION=${PACKAGE_VERSION:1}"" >> $GITHUB_ENV + echo "PACKAGE_VERSION=${PACKAGE_VERSION:1}" >> $GITHUB_ENV elif [[ $PACKAGE_VERSION == [0-9].*.*.* ]]; then - echo "PACKAGE_VERSION=${PACKAGE_VERSION:0}"" >> $GITHUB_ENV + echo "PACKAGE_VERSION=${PACKAGE_VERSION:0}" >> $GITHUB_ENV else echo "PACKAGE_VERSION=0.0.0.0" >> $GITHUB_ENV fi From 1ee15c1b999d310b9d5b41bc66c9e8c683b495e4 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sun, 28 Apr 2024 22:48:37 -0400 Subject: [PATCH 045/128] merged main-dev --- src/mtconnect/agent.cpp | 4 ++-- src/mtconnect/device_model/data_item/data_item.cpp | 2 +- src/mtconnect/device_model/data_item/data_item.hpp | 4 ++-- test_package/agent_test.cpp | 3 +-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index 864d7f1a4..958912a3f 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -299,7 +299,7 @@ namespace mtconnect { { if (item.expired()) continue; - + auto di = item.lock(); if (di->hasInitialValue()) { @@ -307,7 +307,7 @@ namespace mtconnect { } } } - + std::lock_guard lock(m_circularBuffer); if (m_circularBuffer.addToBuffer(observation) != 0) { diff --git a/src/mtconnect/device_model/data_item/data_item.cpp b/src/mtconnect/device_model/data_item/data_item.cpp index 53f238b95..b0596fbd1 100644 --- a/src/mtconnect/device_model/data_item/data_item.cpp +++ b/src/mtconnect/device_model/data_item/data_item.cpp @@ -201,7 +201,7 @@ namespace mtconnect { } } } - + if (const auto &init = maybeGet("InitialValue"); init) { m_initialValue = *init; diff --git a/src/mtconnect/device_model/data_item/data_item.hpp b/src/mtconnect/device_model/data_item/data_item.hpp index 7f62fdbd8..8a7c6959c 100644 --- a/src/mtconnect/device_model/data_item/data_item.hpp +++ b/src/mtconnect/device_model/data_item/data_item.hpp @@ -139,11 +139,11 @@ namespace mtconnect { /// @brief get the topic name leaf node for this data item /// @return the topic name const auto &getTopicName() const { return m_topicName; } - + /// @brief get the initial value if one is set /// @return optional initial value const auto &getInitialValue() const { return m_initialValue; } - + Category getCategory() const { return m_category; } Representation getRepresentation() const { return m_representation; } SpecialClass getSpecialClass() const { return m_specialClass; } diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index f3cabd50d..c859d1a57 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -3139,7 +3139,6 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_fa } } - TEST_F(AgentTest, should_initialize_observaton_to_initial_value_when_available) { m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.2", 4, true); @@ -3153,7 +3152,7 @@ TEST_F(AgentTest, should_initialize_observaton_to_initial_value_when_available) PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:PartCount", "UNAVAILABLE"); } - + m_agentTestHelper->m_adapter->processData("2024-01-22T20:00:00Z|avail|AVAILABLE"); { From a6f5f8f9378a3b846130d15a0ecd1e9f477d3d9c Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sun, 28 Apr 2024 22:54:22 -0400 Subject: [PATCH 046/128] Removed extra character --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5560bb92..2ea263a17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) set(AGENT_VERSION_BUILD 0) -set(AGENT_VERSION_RC "RC2") +set(AGENT_VERSION_RC "RC2") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) From 45e37cbb900b034240d5ee2f2e60365d1ae10956 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sun, 28 Apr 2024 22:55:03 -0400 Subject: [PATCH 047/128] removed exta characters --- CMakeLists.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cd4564cf..2ea263a17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,13 +2,8 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) -<<<<<<< HEAD set(AGENT_VERSION_BUILD 0) -set(AGENT_VERSION_RC "RC2") -======= -set(AGENT_VERSION_BUILD 8) -set(AGENT_VERSION_RC "") ->>>>>>> de28136e (version 2.3.0.8) +set(AGENT_VERSION_RC "RC2") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) From 389aa9f5fbd79637c8720528894ba05baf980ab8 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 2 May 2024 16:56:23 -0400 Subject: [PATCH 048/128] Added initial websocket test --- src/mtconnect/sink/rest_sink/routing.hpp | 6 +- .../sink/rest_sink/websocket_session.hpp | 11 +- test_package/CMakeLists.txt | 1 + test_package/websockets_test.cpp | 246 ++++++++++++++++++ 4 files changed, 260 insertions(+), 4 deletions(-) create mode 100644 test_package/websockets_test.cpp diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index 0710f15b1..bfa584eeb 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -241,7 +241,11 @@ namespace mtconnect::sink::rest_sink { /// @brief Sets the command associated with this routing for use with websockets /// @param command the command - void command(const std::string &command) { m_command = command; } + auto &command(const std::string &command) + { + m_command = command; + return *this; + } protected: void pathParameters(std::string s) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 013d86016..84eda57e2 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -104,7 +104,14 @@ namespace mtconnect::sink::rest_sink { if (!m_isOpen) return; - auto ptr = derived().shared_ptr(); + m_isOpen = false; + + auto wptr = weak_from_this(); + std::shared_ptr ptr; + if (!wptr.expired()) + { + ptr = wptr.lock(); + } m_request.reset(); m_requests.clear(); @@ -117,8 +124,6 @@ namespace mtconnect::sink::rest_sink { } } closeStream(); - - m_isOpen = false; } void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index ec5961013..b0fb4c836 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -245,6 +245,7 @@ add_agent_test(qname FALSE entity) add_agent_test(file_cache FALSE sink/rest_sink) add_agent_test(http_server FALSE sink/rest_sink TRUE) +add_agent_test(websockets FALSE sink/rest_sink TRUE) add_agent_test(tls_http_server FALSE sink/rest_sink TRUE) add_agent_test(routing FALSE sink/rest_sink) diff --git a/test_package/websockets_test.cpp b/test_package/websockets_test.cpp new file mode 100644 index 000000000..0ca154420 --- /dev/null +++ b/test_package/websockets_test.cpp @@ -0,0 +1,246 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Ensure that gtest is the first header otherwise Windows raises an error +#include +// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mtconnect/logging.hpp" +#include "mtconnect/sink/rest_sink/server.hpp" + +using namespace std; +using namespace mtconnect; +using namespace mtconnect::sink::rest_sink; + +namespace asio = boost::asio; +namespace beast = boost::beast; +namespace http = boost::beast::http; +using tcp = boost::asio::ip::tcp; +namespace websocket = beast::websocket; + +// main +int main(int argc, char* argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +class Client +{ +public: + Client(asio::io_context& ioc) : m_context(ioc), m_stream(ioc) {} + + ~Client() { close(); } + + void fail(beast::error_code ec, char const* what) + { + LOG(error) << what << ": " << ec.message() << "\n"; + m_done = true; + m_ec = ec; + } + + void connect(unsigned short port, asio::yield_context yield) + { + beast::error_code ec; + + // These objects perform our I/O + tcp::endpoint server(asio::ip::address_v4::from_string("127.0.0.1"), port); + + // Make the connection on the IP address we get from a lookup + beast::get_lowest_layer(m_stream).async_connect(server, yield[ec]); + + if (ec) + { + return fail(ec, "connect"); + } + + m_stream.set_option(websocket::stream_base::timeout::suggested(beast::role_type::client)); + + m_stream.set_option(websocket::stream_base::decorator([](websocket::request_type& req) { + req.set(http::field::user_agent, + std::string(BOOST_BEAST_VERSION_STRING) + " websocket-client"); + })); + + string host = "127.0.0.1:" + std::to_string(port); + m_stream.async_handshake(host, "/", yield[ec]); + + if (ec) + { + return fail(ec, "connect"); + } + + m_connected = true; + + m_stream.async_read(m_buffer, beast::bind_front_handler(&Client::onRead, this)); + } + + void onRead(beast::error_code ec, std::size_t bytes_transferred) + { + m_result = beast::buffers_to_string(m_buffer.data()); + m_buffer.consume(m_buffer.size()); + + m_done = true; + } + + void request(const string& payload, asio::yield_context yield) + { + cout << "spawnRequest: done: false" << endl; + m_done = false; + beast::error_code ec; + + m_stream.async_write(asio::buffer(payload), yield[ec]); + + waitFor(2s, [this]() { return m_done; }); + } + + template + bool waitFor(const chrono::duration& time, function pred) + { + boost::asio::steady_timer timer(m_context); + timer.expires_from_now(time); + bool timeout = false; + timer.async_wait([&timeout](boost::system::error_code ec) { + if (!ec) + { + timeout = true; + } + }); + + while (!timeout && !pred()) + { + m_context.run_for(500ms); + } + timer.cancel(); + + return pred(); + } + + void close() + { + beast::error_code ec; + + // Gracefully close the socket + m_stream.next_layer().shutdown(tcp::socket::shutdown_both, ec); + } + + bool m_connected {false}; + int m_status; + std::string m_result; + asio::io_context& m_context; + bool m_done {false}; + websocket::stream m_stream; + beast::flat_buffer m_buffer; + boost::beast::error_code m_ec; + beast::flat_buffer m_b; + int m_count {0}; +}; + +class WebsocketsTest : public testing::Test +{ +protected: + void SetUp() override + { + using namespace mtconnect::configuration; + m_server = make_unique(m_context, ConfigOptions {{Port, 0}, {ServerIp, "127.0.0.1"s}}); + } + + void createServer(const ConfigOptions& options) + { + using namespace mtconnect::configuration; + ConfigOptions opts {{Port, 0}, {ServerIp, "127.0.0.1"s}}; + opts.merge(ConfigOptions(options)); + m_server = make_unique(m_context, opts); + } + + void start() + { + m_server->start(); + while (!m_server->isListening()) + m_context.run_one(); + m_client = make_unique(m_context); + } + + void startClient() + { + m_client->m_connected = false; + asio::spawn(m_context, + std::bind(&Client::connect, m_client.get(), + static_cast(m_server->getPort()), std::placeholders::_1)); + + m_client->waitFor(1s, [this]() { return m_client->m_connected; }); + } + + void TearDown() override + { + m_server.reset(); + m_client.reset(); + } + + asio::io_context m_context; + unique_ptr m_server; + unique_ptr m_client; +}; + +TEST_F(WebsocketsTest, should_connect_to_server) +{ + start(); + startClient(); + + ASSERT_TRUE(m_client->m_connected); +} + +TEST_F(WebsocketsTest, should_make_simple_request) +{ + weak_ptr savedSession; + + auto probe = [&](SessionPtr session, RequestPtr request) -> bool { + savedSession = session; + ResponsePtr resp = make_unique(status::ok); + resp->m_body = "All Devices for "s + *request->m_requestId; + resp->m_requestId = request->m_requestId; + session->writeResponse(std::move(resp), []() { cout << "Written" << endl; }); + return true; + }; + + m_server->addRouting({boost::beast::http::verb::get, "/probe", probe}).command("probe"); + m_server->addCommands(); + + start(); + startClient(); + + asio::spawn(m_context, std::bind(&Client::request, m_client.get(), + "{\"id\":\"1\",\"request\":\"probe\"}"s, std::placeholders::_1)); + + m_client->waitFor(2s, [this]() { return m_client->m_done; }); + + ASSERT_TRUE(m_client->m_done); + ASSERT_EQ("All Devices for 1", m_client->m_result); +} From dfdf1d98408f915d2733cca4348bfbd65f24c47d Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 2 May 2024 21:15:39 -0400 Subject: [PATCH 049/128] cast to parameter value --- .../sink/rest_sink/websocket_session.hpp | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 84eda57e2..34ee931e6 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -362,10 +362,12 @@ namespace mtconnect::sink::rest_sink { // Skip nulls break; case rapidjson::kFalseType: - request->m_parameters.emplace(make_pair(it.name.GetString(), false)); + request->m_parameters.emplace( + make_pair(it.name.GetString(), ParameterValue(bool(false)))); break; case rapidjson::kTrueType: - request->m_parameters.emplace(make_pair(it.name.GetString(), true)); + request->m_parameters.emplace( + make_pair(it.name.GetString(), ParameterValue(bool(true)))); break; case rapidjson::kObjectType: break; @@ -373,24 +375,25 @@ namespace mtconnect::sink::rest_sink { break; case rapidjson::kStringType: request->m_parameters.emplace( - make_pair(it.name.GetString(), string(it.value.GetString()))); + make_pair(it.name.GetString(), ParameterValue(it.value.GetString()))); break; case rapidjson::kNumberType: if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + request->m_parameters.emplace( + make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); else if (it.value.Is()) request->m_parameters.emplace( - make_pair(it.name.GetString(), it.value.Get())); + make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); else if (it.value.Is()) - request->m_parameters.emplace( - make_pair(it.name.GetString(), (uint64_t)it.value.Get())); + request->m_parameters.emplace(make_pair( + it.name.GetString(), ParameterValue((uint64_t)it.value.Get()))); else if (it.value.Is()) request->m_parameters.emplace( - make_pair(it.name.GetString(), it.value.Get())); + make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); else if (it.value.Is()) request->m_parameters.emplace( - make_pair(it.name.GetString(), it.value.Get())); + make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); break; } From e80975b862ab748bb84548931d9d062872e63a19 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 2 May 2024 22:48:40 -0400 Subject: [PATCH 050/128] windows port of websockets --- agent_lib/CMakeLists.txt | 2 +- .../sink/rest_sink/websocket_session.hpp | 36 +++++++++++-------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index c39284674..03ca6fd80 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -335,8 +335,8 @@ if(MSVC) # The modules including Beast required the /bigobj option in Windows set_property(SOURCE + "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.cpp" "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" - "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.cpp" "${SOURCE_DIR}/sink/rest_sink/session_impl.cpp" "${SOURCE_DIR}/source/adapter/mqtt/mqtt_adapter.cpp" "${SOURCE_DIR}/source/adapter/agent_adapter/agent_adapter.cpp" diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 34ee931e6..7a84bfbce 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -352,7 +352,15 @@ namespace mtconnect::sink::rest_sink { request->m_verb = beast::http::verb::get; request->m_parameters.clear(); +#ifdef GetObject +#define __GOSave__ GetObject +#undef GetObject +#endif + const auto &object = doc.GetObject(); +#ifdef __GOSave__ +#define GetObject __GOSave__ +#endif for (auto &it : object) { @@ -363,11 +371,11 @@ namespace mtconnect::sink::rest_sink { break; case rapidjson::kFalseType: request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(bool(false)))); + make_pair(string(it.name.GetString()), ParameterValue(false))); break; case rapidjson::kTrueType: request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(bool(true)))); + make_pair(string(it.name.GetString()), ParameterValue(true))); break; case rapidjson::kObjectType: break; @@ -375,25 +383,25 @@ namespace mtconnect::sink::rest_sink { break; case rapidjson::kStringType: request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(it.value.GetString()))); + make_pair(it.name.GetString(), ParameterValue(string(it.value.GetString())))); break; case rapidjson::kNumberType: - if (it.value.Is()) + if (it.value.IsInt()) + request->m_parameters.emplace( + make_pair(it.name.GetString(), ParameterValue(it.value.GetInt()))); + else if (it.value.IsUint()) request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); - else if (it.value.Is()) + make_pair(it.name.GetString(), ParameterValue(uint64_t(it.value.GetUint())))); + else if (it.value.IsInt64()) request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); - else if (it.value.Is()) - request->m_parameters.emplace(make_pair( - it.name.GetString(), ParameterValue((uint64_t)it.value.Get()))); - else if (it.value.Is()) + make_pair(it.name.GetString(), ParameterValue(uint64_t(it.value.GetInt64())))); + else if (it.value.IsUint64()) request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); - else if (it.value.Is()) + make_pair(it.name.GetString(), ParameterValue(it.value.GetUint64()))); + else if (it.value.IsDouble()) request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); + make_pair(it.name.GetString(), ParameterValue(double(it.value.GetDouble())))); break; } From eb350cb36fff661563839b646b46bc78d5422444 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 3 May 2024 04:44:30 -0400 Subject: [PATCH 051/128] removed named scope from websocket session --- src/mtconnect/sink/rest_sink/websocket_session.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 7a84bfbce..c0bd12a2a 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -100,7 +100,7 @@ namespace mtconnect::sink::rest_sink { void close() override { - NAMED_SCOPE("PlainWebsocketSession::close"); + //NAMED_SCOPE("PlainWebsocketSession::close"); if (!m_isOpen) return; @@ -128,7 +128,7 @@ namespace mtconnect::sink::rest_sink { void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { - NAMED_SCOPE("WebsocketSession::writeResponse"); + //NAMED_SCOPE("WebsocketSession::writeResponse"); if (!response->m_requestId) { boost::system::error_code ec; @@ -140,7 +140,7 @@ namespace mtconnect::sink::rest_sink { void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override { - NAMED_SCOPE("WebsocketSession::writeFailureResponse"); + //NAMED_SCOPE("WebsocketSession::writeFailureResponse"); writeChunk(response->m_body, complete, response->m_requestId); } @@ -175,7 +175,7 @@ namespace mtconnect::sink::rest_sink { void writeChunk(const std::string &chunk, Complete complete, std::optional requestId = std::nullopt) override { - NAMED_SCOPE("WebsocketSession::writeChunk"); + //NAMED_SCOPE("WebsocketSession::writeChunk"); if (!derived().stream().is_open()) { @@ -219,7 +219,7 @@ namespace mtconnect::sink::rest_sink { void send(const std::string body, Complete complete, const std::string &requestId) { - NAMED_SCOPE("WebsocketSession::send"); + //NAMED_SCOPE("WebsocketSession::send"); using namespace std::placeholders; @@ -255,7 +255,7 @@ namespace mtconnect::sink::rest_sink { void sent(beast::error_code ec, std::size_t len, const std::string &id) { - NAMED_SCOPE("WebsocketSession::sent"); + //NAMED_SCOPE("WebsocketSession::sent"); if (ec) { @@ -310,7 +310,7 @@ namespace mtconnect::sink::rest_sink { void onRead(beast::error_code ec, std::size_t len) { - NAMED_SCOPE("PlainWebsocketSession::onRead"); + //NAMED_SCOPE("PlainWebsocketSession::onRead"); if (ec) return fail(boost::beast::http::status::internal_server_error, "shutdown", ec); From 8c92d733663d71879b19436e5339d1a114f009f8 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 3 May 2024 05:49:44 -0400 Subject: [PATCH 052/128] Added BOOST_USE_WINAPI_VERSION for boost 1.84 --- conan/profiles/vs32 | 1 + conan/profiles/vs32debug | 1 + conan/profiles/vs32shared | 1 + conanfile.py | 3 ++- src/mtconnect/sink/rest_sink/websocket_session.hpp | 14 +++++++------- 5 files changed, 12 insertions(+), 8 deletions(-) diff --git a/conan/profiles/vs32 b/conan/profiles/vs32 index f78b6c433..a053784c9 100644 --- a/conan/profiles/vs32 +++ b/conan/profiles/vs32 @@ -3,6 +3,7 @@ include(default) [settings] compiler=msvc compiler.cppstd=17 +winver=0x0600 arch=x86 compiler.runtime=static compiler.runtime_type=Release diff --git a/conan/profiles/vs32debug b/conan/profiles/vs32debug index 445637905..b725433f3 100644 --- a/conan/profiles/vs32debug +++ b/conan/profiles/vs32debug @@ -3,6 +3,7 @@ include(default) [settings] compiler=msvc compiler.cppstd=17 +winver=0x0600 arch=x86 compiler.runtime=static compiler.runtime_type=Debug diff --git a/conan/profiles/vs32shared b/conan/profiles/vs32shared index cac3622ed..c8f19481d 100644 --- a/conan/profiles/vs32shared +++ b/conan/profiles/vs32shared @@ -4,6 +4,7 @@ include(default) compiler=msvc compiler.cppstd=17 arch=x86 +winver=0x0600 compiler.runtime=dynamic compiler.runtime_type=Release build_type=Release diff --git a/conanfile.py b/conanfile.py index 2c384fb36..609165726 100644 --- a/conanfile.py +++ b/conanfile.py @@ -35,7 +35,7 @@ class MTConnectAgentConan(ConanFile): "with_ruby": True, "development": False, "shared": False, - "winver": "0x600", + "winver": "0x602", "with_docs": False, "cpack": False, "agent_prefix": None, @@ -227,6 +227,7 @@ def package_info(self): winver=str(self.options.winver) self.cpp_info.defines.append("WINVER=" + winver) self.cpp_info.defines.append("_WIN32_WINNT=" + winver) + self.cpp_info.defines.append("BOOST_USE_WINAPI_VERSION=" + winver) def package(self): cmake = CMake(self) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index c0bd12a2a..7a84bfbce 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -100,7 +100,7 @@ namespace mtconnect::sink::rest_sink { void close() override { - //NAMED_SCOPE("PlainWebsocketSession::close"); + NAMED_SCOPE("PlainWebsocketSession::close"); if (!m_isOpen) return; @@ -128,7 +128,7 @@ namespace mtconnect::sink::rest_sink { void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { - //NAMED_SCOPE("WebsocketSession::writeResponse"); + NAMED_SCOPE("WebsocketSession::writeResponse"); if (!response->m_requestId) { boost::system::error_code ec; @@ -140,7 +140,7 @@ namespace mtconnect::sink::rest_sink { void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override { - //NAMED_SCOPE("WebsocketSession::writeFailureResponse"); + NAMED_SCOPE("WebsocketSession::writeFailureResponse"); writeChunk(response->m_body, complete, response->m_requestId); } @@ -175,7 +175,7 @@ namespace mtconnect::sink::rest_sink { void writeChunk(const std::string &chunk, Complete complete, std::optional requestId = std::nullopt) override { - //NAMED_SCOPE("WebsocketSession::writeChunk"); + NAMED_SCOPE("WebsocketSession::writeChunk"); if (!derived().stream().is_open()) { @@ -219,7 +219,7 @@ namespace mtconnect::sink::rest_sink { void send(const std::string body, Complete complete, const std::string &requestId) { - //NAMED_SCOPE("WebsocketSession::send"); + NAMED_SCOPE("WebsocketSession::send"); using namespace std::placeholders; @@ -255,7 +255,7 @@ namespace mtconnect::sink::rest_sink { void sent(beast::error_code ec, std::size_t len, const std::string &id) { - //NAMED_SCOPE("WebsocketSession::sent"); + NAMED_SCOPE("WebsocketSession::sent"); if (ec) { @@ -310,7 +310,7 @@ namespace mtconnect::sink::rest_sink { void onRead(beast::error_code ec, std::size_t len) { - //NAMED_SCOPE("PlainWebsocketSession::onRead"); + NAMED_SCOPE("PlainWebsocketSession::onRead"); if (ec) return fail(boost::beast::http::status::internal_server_error, "shutdown", ec); From b23b28b123bd1a1fa65efec5ebee5f7f3ccbf283 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 3 May 2024 10:17:57 -0400 Subject: [PATCH 053/128] added boost windows api version for windows 1.84 porting --- conan/profiles/vs32 | 3 ++- conan/profiles/vs32debug | 4 +++- conan/profiles/vs32shared | 2 +- conanfile.py | 5 ++++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/conan/profiles/vs32 b/conan/profiles/vs32 index a053784c9..fb406b017 100644 --- a/conan/profiles/vs32 +++ b/conan/profiles/vs32 @@ -3,9 +3,10 @@ include(default) [settings] compiler=msvc compiler.cppstd=17 -winver=0x0600 arch=x86 compiler.runtime=static compiler.runtime_type=Release build_type=Release +[options] +winver=0x0600 diff --git a/conan/profiles/vs32debug b/conan/profiles/vs32debug index b725433f3..54344e405 100644 --- a/conan/profiles/vs32debug +++ b/conan/profiles/vs32debug @@ -3,8 +3,10 @@ include(default) [settings] compiler=msvc compiler.cppstd=17 -winver=0x0600 arch=x86 compiler.runtime=static compiler.runtime_type=Debug build_type=Debug + +[options] +winver=0x0600 diff --git a/conan/profiles/vs32shared b/conan/profiles/vs32shared index c8f19481d..9bf550dbe 100644 --- a/conan/profiles/vs32shared +++ b/conan/profiles/vs32shared @@ -4,10 +4,10 @@ include(default) compiler=msvc compiler.cppstd=17 arch=x86 -winver=0x0600 compiler.runtime=dynamic compiler.runtime_type=Release build_type=Release [options] shared=True +winver=0x0600 diff --git a/conanfile.py b/conanfile.py index 609165726..02cd0438a 100644 --- a/conanfile.py +++ b/conanfile.py @@ -35,7 +35,7 @@ class MTConnectAgentConan(ConanFile): "with_ruby": True, "development": False, "shared": False, - "winver": "0x602", + "winver": "0x0602", "with_docs": False, "cpack": False, "agent_prefix": None, @@ -139,6 +139,9 @@ def configure(self): if self.options.shared: self.options["boost/*"].shared = True self.package_type = "shared-library" + + if is_msvc(self): + self.options["boost/*"].extra_b2_flags = ("define=BOOST_USE_WINAPI_VERSION=" + str(self.options.winver)) # Make sure shared builds use shared boost if is_msvc(self) and self.options.shared: From ca11039fbf4eabcdcb9a10f0aee02f3df4ea591f Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 3 May 2024 11:45:33 -0400 Subject: [PATCH 054/128] removed legacy mqtt service --- agent_lib/CMakeLists.txt | 3 - src/mtconnect/configuration/agent_config.cpp | 2 - .../sink/mqtt_sink/mqtt_legacy_service.cpp | 197 ------ .../sink/mqtt_sink/mqtt_legacy_service.hpp | 107 --- src/mtconnect/sink/rest_sink/rest_service.cpp | 4 +- test_package/CMakeLists.txt | 1 - test_package/agent_test_helper.hpp | 23 - test_package/mqtt_isolated_test.cpp | 2 +- test_package/mqtt_legacy_sink_test.cpp | 630 ------------------ test_package/mqtt_sink_test.cpp | 17 +- 10 files changed, 12 insertions(+), 974 deletions(-) delete mode 100644 src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp delete mode 100644 src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp delete mode 100644 test_package/mqtt_legacy_sink_test.cpp diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index 03ca6fd80..9571fc07b 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -246,12 +246,10 @@ set(AGENT_SOURCES # src/sink/mqtt_sink HEADER_FILE_ONLY - "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.hpp" "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.hpp" #src/sink/mqtt_sink SOURCE_FILES_ONLY - "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.cpp" "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" # src/sink/rest_sink HEADER_FILE_ONLY @@ -335,7 +333,6 @@ if(MSVC) # The modules including Beast required the /bigobj option in Windows set_property(SOURCE - "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.cpp" "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" "${SOURCE_DIR}/sink/rest_sink/session_impl.cpp" "${SOURCE_DIR}/source/adapter/mqtt/mqtt_adapter.cpp" diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index d372df52a..e9bf4013c 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -58,7 +58,6 @@ #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/device_model/device.hpp" #include "mtconnect/printer/xml_printer.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" #include "mtconnect/sink/mqtt_sink/mqtt_service.hpp" #include "mtconnect/sink/rest_sink/rest_service.hpp" #include "mtconnect/source/adapter/agent_adapter/agent_adapter.hpp" @@ -112,7 +111,6 @@ namespace mtconnect::configuration { bool success = false; - sink::mqtt_sink::MqttLegacyService::registerFactory(m_sinkFactory); sink::mqtt_sink::MqttService::registerFactory(m_sinkFactory); sink::rest_sink::RestService::registerFactory(m_sinkFactory); adapter::shdr::ShdrAdapter::registerFactory(m_sourceFactory); diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp deleted file mode 100644 index 46aea8a12..000000000 --- a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp +++ /dev/null @@ -1,197 +0,0 @@ -// -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#include "mqtt_legacy_service.hpp" - -#include "mtconnect/configuration/config_options.hpp" -#include "mtconnect/entity/entity.hpp" -#include "mtconnect/entity/factory.hpp" -#include "mtconnect/entity/json_parser.hpp" -#include "mtconnect/mqtt/mqtt_client_impl.hpp" -#include "mtconnect/printer/json_printer.hpp" - -using ptree = boost::property_tree::ptree; - -using namespace std; -using namespace mtconnect::asset; - -namespace asio = boost::asio; -namespace config = ::mtconnect::configuration; - -namespace mtconnect { - namespace sink { - namespace mqtt_sink { - // get obeservation in - // create a json printer - // call print - - MqttLegacyService::MqttLegacyService(boost::asio::io_context &context, - sink::SinkContractPtr &&contract, - const ConfigOptions &options, const ptree &config) - : Sink("MqttLegacyService", std::move(contract)), m_context(context), m_options(options) - { - auto jsonPrinter = dynamic_cast(m_sinkContract->getPrinter("json")); - m_jsonPrinter = make_unique(jsonPrinter->getJsonVersion()); - - GetOptions(config, m_options, options); - AddOptions(config, m_options, - {{configuration::ProbeTopic, string()}, - {configuration::MqttCaCert, string()}, - {configuration::MqttPrivateKey, string()}, - {configuration::MqttCert, string()}, - {configuration::MqttUserName, string()}, - {configuration::MqttPassword, string()}, - {configuration::MqttClientId, string()}}); - AddDefaultedOptions(config, m_options, - {{configuration::MqttHost, "127.0.0.1"s}, - {configuration::DeviceTopic, "MTConnect/Device/"s}, - {configuration::AssetTopic, "MTConnect/Asset/"s}, - {configuration::ObservationTopic, "MTConnect/Observation/"s}, - {configuration::MqttPort, 1883}, - {configuration::MqttTls, false}}); - - auto clientHandler = make_unique(); - clientHandler->m_connected = [this](shared_ptr client) { - // Publish latest devices, assets, and observations - auto &circ = m_sinkContract->getCircularBuffer(); - std::lock_guard lock(circ); - client->connectComplete(); - - for (auto &dev : m_sinkContract->getDevices()) - { - publish(dev); - } - - auto obsList {circ.getLatest().getObservations()}; - for (auto &obs : obsList) - { - observation::ObservationPtr p {obs.second}; - publish(p); - } - - AssetList list; - m_sinkContract->getAssetStorage()->getAssets(list, 100000); - for (auto &asset : list) - { - publish(asset); - } - }; - - m_devicePrefix = GetOption(m_options, configuration::ProbeTopic) - .value_or(get(m_options[configuration::DeviceTopic])); - m_assetPrefix = get(m_options[configuration::AssetTopic]); - m_observationPrefix = get(m_options[configuration::ObservationTopic]); - - if (IsOptionSet(m_options, configuration::MqttTls)) - { - m_client = make_shared(m_context, m_options, std::move(clientHandler)); - } - else - { - m_client = make_shared(m_context, m_options, std::move(clientHandler)); - } - } - - void MqttLegacyService::start() - { - // mqtt client side not a server side... - if (!m_client) - return; - - m_client->start(); - } - - void MqttLegacyService::stop() - { - // stop client side - if (m_client) - m_client->stop(); - } - - std::shared_ptr MqttLegacyService::getClient() { return m_client; } - - bool MqttLegacyService::publish(observation::ObservationPtr &observation) - { - // get the data item from observation - if (observation->isOrphan()) - return false; - - DataItemPtr dataItem = observation->getDataItem(); - - auto topic = m_observationPrefix + dataItem->getTopic(); // client asyn topic - auto content = dataItem->getTopicName(); // client asyn content - - // We may want to use the observation from the checkpoint. - string doc; - if (observation->getDataItem()->isCondition()) - { - doc = m_jsonPrinter->print(observation); - } - else - { - doc = m_jsonPrinter->printEntity(observation); - } - - if (m_client) - m_client->publish(topic, doc); - - return true; - } - - bool MqttLegacyService::publish(device_model::DevicePtr device) - { - auto topic = m_devicePrefix + *device->getUuid(); - auto doc = m_jsonPrinter->print(device); - - stringstream buffer; - buffer << doc; - - if (m_client) - m_client->publish(topic, buffer.str()); - - return true; - } - - bool MqttLegacyService::publish(asset::AssetPtr asset) - { - auto topic = m_assetPrefix + get(asset->getIdentity()); - auto doc = m_jsonPrinter->print(asset); - - stringstream buffer; - buffer << doc; - - if (m_client) - m_client->publish(topic, buffer.str()); - - return true; - } - - // Register the service with the sink factory - void MqttLegacyService::registerFactory(SinkFactory &factory) - { - factory.registerFactory( - "MqttLegacyService", - [](const std::string &name, boost::asio::io_context &io, SinkContractPtr &&contract, - const ConfigOptions &options, const boost::property_tree::ptree &block) -> SinkPtr { - auto sink = - std::make_shared(io, std::move(contract), options, block); - return sink; - }); - } - } // namespace mqtt_sink - } // namespace sink -} // namespace mtconnect diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp deleted file mode 100644 index ab84d97d5..000000000 --- a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp +++ /dev/null @@ -1,107 +0,0 @@ -// -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#pragma once - -#include "boost/asio/io_context.hpp" -#include - -#include "mtconnect/buffer/checkpoint.hpp" -#include "mtconnect/config.hpp" -#include "mtconnect/configuration/agent_config.hpp" -#include "mtconnect/entity/json_printer.hpp" -#include "mtconnect/mqtt/mqtt_client.hpp" -#include "mtconnect/observation/observation.hpp" -#include "mtconnect/printer/printer.hpp" -#include "mtconnect/printer/xml_printer_helper.hpp" -#include "mtconnect/sink/sink.hpp" -#include "mtconnect/utilities.hpp" - -using namespace std; -using namespace mtconnect::entity; -using namespace mtconnect::mqtt_client; - -namespace mtconnect { - class XmlPrinter; - - namespace sink { - - /// @brief MTConnect Mqtt implemention namespace - - namespace mqtt_sink { - class AGENT_LIB_API MqttLegacyService : public sink::Sink - { - // dynamic loading of sink - - public: - /// @brief Create a Mqtt Service sink - /// @param context the boost asio io_context - /// @param contract the Sink Contract from the agent - /// @param options configuration options - /// @param config additional configuration options if specified directly as a sink - MqttLegacyService(boost::asio::io_context &context, sink::SinkContractPtr &&contract, - const ConfigOptions &options, const boost::property_tree::ptree &config); - - ~MqttLegacyService() = default; - - // Sink Methods - /// @brief Start the Mqtt service - void start() override; - - /// @brief Shutdown the Mqtt service - void stop() override; - - /// @brief Receive an observation - /// @param observation shared pointer to the observation - /// @return `true` if the publishing was successful - bool publish(observation::ObservationPtr &observation) override; - - /// @brief Receive an asset - /// @param asset shared point to the asset - /// @return `true` if successful - bool publish(asset::AssetPtr asset) override; - - /// @brief Receive a device - /// @param device shared pointer to the device - /// @return `true` if successful - bool publish(device_model::DevicePtr device) override; - - /// @brief Register the Sink factory to create this sink - /// @param factory - static void registerFactory(SinkFactory &factory); - - /// @brief gets a Mqtt Client - /// @return MqttClient - std::shared_ptr getClient(); - - /// @brief Mqtt Client is Connected or not - /// @return `true` when the client was connected - bool isConnected() { return m_client && m_client->isConnected(); } - - protected: - std::string m_devicePrefix; - std::string m_assetPrefix; - std::string m_observationPrefix; - - boost::asio::io_context &m_context; - ConfigOptions m_options; - std::unique_ptr m_jsonPrinter; - std::shared_ptr m_client; - }; - } // namespace mqtt_sink - } // namespace sink -} // namespace mtconnect diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 82c1df6cc..210865470 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -531,7 +531,7 @@ namespace mtconnect { auto handler = [&](SessionPtr session, RequestPtr request) -> bool { auto removed = *request->parameter("removed"); auto count = *request->parameter("count"); - auto pretty = *request->parameter("pretty"); + auto pretty = request->parameter("pretty").value_or(false); auto format = request->parameter("format"); auto printer = getPrinter(request->m_accepts, format); @@ -546,7 +546,7 @@ namespace mtconnect { auto asset = request->parameter("assetIds"); if (asset) { - auto pretty = *request->parameter("pretty"); + auto pretty = request->parameter("pretty").value_or(false); auto printer = m_sinkContract->getPrinter(acceptFormat(request->m_accepts)); list ids; diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index b0fb4c836..05427a32d 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -250,7 +250,6 @@ add_agent_test(tls_http_server FALSE sink/rest_sink TRUE) add_agent_test(routing FALSE sink/rest_sink) add_agent_test(mqtt_isolated FALSE mqtt_isolated TRUE) -add_agent_test(mqtt_legacy_sink FALSE sink/mqtt_legacy_sink TRUE) add_agent_test(mqtt_sink FALSE sink/mqtt_sink TRUE) add_agent_test(json_printer_asset TRUE json) diff --git a/test_package/agent_test_helper.hpp b/test_package/agent_test_helper.hpp index 4d16eb475..16c7a5cf7 100644 --- a/test_package/agent_test_helper.hpp +++ b/test_package/agent_test_helper.hpp @@ -29,7 +29,6 @@ #include "mtconnect/configuration/agent_config.hpp" #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/pipeline/pipeline.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" #include "mtconnect/sink/mqtt_sink/mqtt_service.hpp" #include "mtconnect/sink/rest_sink/response.hpp" #include "mtconnect/sink/rest_sink/rest_service.hpp" @@ -124,7 +123,6 @@ class AgentTestHelper ~AgentTestHelper() { - m_mqttLegacyService.reset(); m_mqttService.reset(); m_restService.reset(); m_adapter.reset(); @@ -171,15 +169,6 @@ class AgentTestHelper return rest; } - std::shared_ptr getMqttLegacyService() - { - using namespace mtconnect; - sink::SinkPtr sink = m_agent->findSink("MqttLegacyService"); - std::shared_ptr mqtt = - std::dynamic_pointer_cast(sink); - return mqtt; - } - std::shared_ptr getMqttService() { using namespace mtconnect; @@ -199,7 +188,6 @@ class AgentTestHelper using ptree = boost::property_tree::ptree; sink::rest_sink::RestService::registerFactory(m_sinkFactory); - sink::mqtt_sink::MqttLegacyService::registerFactory(m_sinkFactory); sink::mqtt_sink::MqttService::registerFactory(m_sinkFactory); source::adapter::shdr::ShdrAdapter::registerFactory(m_sourceFactory); @@ -232,16 +220,6 @@ class AgentTestHelper m_restService = std::dynamic_pointer_cast(sink); m_agent->addSink(m_restService); - if (HasOption(options, "MqttLegacySink")) - { - auto mqttContract = m_agent->makeSinkContract(); - mqttContract->m_pipelineContext = m_context; - auto mqttsink = m_sinkFactory.make("MqttLegacyService", "MqttLegacyService", m_ioContext, - std::move(mqttContract), options, ptree {}); - m_mqttLegacyService = std::dynamic_pointer_cast(mqttsink); - m_agent->addSink(m_mqttLegacyService); - } - if (HasOption(options, "MqttSink")) { auto mqttContract = m_agent->makeSinkContract(); @@ -324,7 +302,6 @@ class AgentTestHelper mhttp::Server *m_server {nullptr}; std::shared_ptr m_context; std::shared_ptr m_adapter; - std::shared_ptr m_mqttLegacyService; std::shared_ptr m_mqttService; std::shared_ptr m_restService; std::shared_ptr m_loopback; diff --git a/test_package/mqtt_isolated_test.cpp b/test_package/mqtt_isolated_test.cpp index 4e7cbc566..9789436c5 100644 --- a/test_package/mqtt_isolated_test.cpp +++ b/test_package/mqtt_isolated_test.cpp @@ -181,7 +181,7 @@ class MqttIsolatedUnitTest : public testing::Test std::unique_ptr m_jsonPrinter; std::shared_ptr m_server; std::shared_ptr m_client; - std::shared_ptr m_service; + std::shared_ptr m_service; std::unique_ptr m_agentTestHelper; uint16_t m_port {0}; }; diff --git a/test_package/mqtt_legacy_sink_test.cpp b/test_package/mqtt_legacy_sink_test.cpp deleted file mode 100644 index 4647c924e..000000000 --- a/test_package/mqtt_legacy_sink_test.cpp +++ /dev/null @@ -1,630 +0,0 @@ -// -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -/// @file -/// Test MQTT 1 Service - -// Ensure that gtest is the first header otherwise Windows raises an error -#include -// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) - -#include - -#include - -#include "agent_test_helper.hpp" -#include "mtconnect/buffer/checkpoint.hpp" -#include "mtconnect/device_model/data_item/data_item.hpp" -#include "mtconnect/entity/entity.hpp" -#include "mtconnect/entity/json_parser.hpp" -#include "mtconnect/mqtt/mqtt_client_impl.hpp" -#include "mtconnect/mqtt/mqtt_server_impl.hpp" -#include "mtconnect/printer//json_printer.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" - -using namespace std; -using namespace mtconnect; -using namespace mtconnect::device_model::data_item; -using namespace mtconnect::sink::mqtt_sink; -using namespace mtconnect::asset; -using namespace mtconnect::configuration; - -// main -int main(int argc, char *argv[]) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - -using json = nlohmann::json; - -class MqttSinkTest : public testing::Test -{ -protected: - void SetUp() override - { - m_agentTestHelper = make_unique(); - m_jsonPrinter = std::make_unique(2, true); - } - - void TearDown() override - { - const auto agent = m_agentTestHelper->getAgent(); - if (agent) - { - m_agentTestHelper->getAgent()->stop(); - m_agentTestHelper->m_ioContext.run_for(100ms); - } - if (m_client) - { - m_client->stop(); - m_agentTestHelper->m_ioContext.run_for(100ms); - m_client.reset(); - } - if (m_server) - { - m_server->stop(); - m_agentTestHelper->m_ioContext.run_for(500ms); - m_server.reset(); - } - m_agentTestHelper.reset(); - m_jsonPrinter.reset(); - } - - void createAgent(std::string testFile = {}, ConfigOptions options = {}) - { - if (testFile == "") - testFile = "/samples/test_config.xml"; - - ConfigOptions opts(options); - MergeOptions(opts, {{"MqttLegacySink", true}, - {configuration::MqttPort, m_port}, - {configuration::MqttHost, "127.0.0.1"s}}); - m_agentTestHelper->createAgent(testFile, 8, 4, "2.0", 25, false, true, opts); - addAdapter(); - - m_agentTestHelper->getAgent()->start(); - } - - void createServer(const ConfigOptions &options) - { - using namespace mtconnect::configuration; - ConfigOptions opts(options); - MergeOptions(opts, {{ServerIp, "127.0.0.1"s}, - {MqttPort, 0}, - {MqttTls, false}, - {AutoAvailable, false}, - {RealTime, false}}); - - m_server = - make_shared(m_agentTestHelper->m_ioContext, opts); - } - - template - bool waitFor(const chrono::duration &time, function pred) - { - boost::asio::steady_timer timer(m_agentTestHelper->m_ioContext); - timer.expires_from_now(time); - bool timeout = false; - timer.async_wait([&timeout](boost::system::error_code ec) { - if (!ec) - { - timeout = true; - } - }); - - while (!timeout && !pred()) - { - m_agentTestHelper->m_ioContext.run_for(100ms); - } - timer.cancel(); - - return pred(); - } - - void startServer() - { - if (m_server) - { - bool start = m_server->start(); - if (start) - { - m_port = m_server->getPort(); - m_agentTestHelper->m_ioContext.run_for(500ms); - } - } - } - - void createClient(const ConfigOptions &options, unique_ptr &&handler) - { - ConfigOptions opts(options); - MergeOptions(opts, {{MqttHost, "127.0.0.1"s}, - {MqttPort, m_port}, - {MqttTls, false}, - {AutoAvailable, false}, - {RealTime, false}}); - m_client = make_shared(m_agentTestHelper->m_ioContext, - opts, std::move(handler)); - } - - bool startClient() - { - bool started = m_client && m_client->start(); - if (started) - { - return waitFor(5s, [this]() { return m_client->isConnected(); }); - } - return started; - } - - void addAdapter(ConfigOptions options = ConfigOptions {}) - { - m_agentTestHelper->addAdapter(options, "localhost", 0, - m_agentTestHelper->m_agent->getDefaultDevice()->getName()); - } - - std::unique_ptr m_jsonPrinter; - std::shared_ptr m_server; - std::shared_ptr m_client; - std::shared_ptr m_service; - std::unique_ptr m_agentTestHelper; - uint16_t m_port {0}; -}; - -TEST_F(MqttSinkTest, mqtt_sink_should_be_loaded_by_agent) -{ - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - - ASSERT_TRUE(service); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker) -{ - ConfigOptions options; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_with_UserNameandPassword) -{ - ConfigOptions options {{MqttUserName, "MQTT-SINK"s}, {MqttPassword, "mtconnect"s}}; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent("", options); - auto service = m_agentTestHelper->getMqttLegacyService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_without_UserNameandPassword) -{ - ConfigOptions options; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_device) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotDevice = false; - handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Device/000", topic); - - ErrorList list; - auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); - EXPECT_EQ(0, list.size()); - auto dev = dynamic_pointer_cast(ptr); - EXPECT_TRUE(dev); - EXPECT_EQ("LinuxCNC", dev->getComponentName()); - EXPECT_EQ("000", *dev->getUuid()); - - gotDevice = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Device/000"); - - createAgent(); - - auto service = m_agentTestHelper->getMqttLegacyService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - - ASSERT_TRUE(waitFor(5s, [&gotDevice]() { return gotDevice; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Streams) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool foundLineDataItem = false; - handler->m_receive = [&foundLineDataItem](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]", topic); - - auto jdoc = json::parse(payload); - string value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ("204", value); - foundLineDataItem = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - - m_client->subscribe("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]"); - m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); - - ASSERT_TRUE(waitFor(5s, [&foundLineDataItem]() { return foundLineDataItem; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Asset) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Asset/0001", topic); - auto jdoc = json::parse(payload); - string id = jdoc.at("/Part/assetId"_json_pointer).get(); - EXPECT_EQ("0001", id); - gotControllerDataItem = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Asset/0001"); - - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|@ASSET@|@1|Part|TEST 1"); - - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_RotaryMode) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotRotaryMode = false; - handler->m_receive = [&gotRotaryMode](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]", - topic); - auto jdoc = json::parse(payload); - - double v = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(5000.0, v); - gotRotaryMode = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]"); - - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|block|G01X00|Sspeed|5000|line|204"); - - ASSERT_TRUE(waitFor(5s, [&gotRotaryMode]() { return gotRotaryMode; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Dataset) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]", - topic); - auto jdoc = json::parse(payload); - auto id = jdoc.at("/value/a"_json_pointer).get(); - EXPECT_EQ(1, id); - gotControllerDataItem = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent("/samples/data_set.xml"); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]"); - - m_agentTestHelper->m_adapter->processData("TIME|vars|a=1 b=2 c=3"); - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Table) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/WorkOffsetTable[wpo]", - topic); - auto jdoc = json::parse(payload); - - auto jValue = jdoc.at("/value"_json_pointer); - int count = 0; - if (jValue.is_object()) - { - for (auto &[key, value] : jValue.items()) - { - if (key == "G53.1" || key == "G53.2" || key == "G53.3") - { - for (auto &[subKey, subValue] : value.items()) - { - if (key == "G53.1" && ((subKey == "X" && subValue.get() == 1) || - (subKey == "Y" && subValue.get() == 2) || - (subKey == "Z" && subValue.get() == 3))) - { - count++; - } - else if (key == "G53.2" && ((subKey == "X" && subValue.get() == 4) || - (subKey == "Y" && subValue.get() == 5) || - (subKey == "Z" && subValue.get() == 6))) - { - count++; - } - else if (key == "G53.3" && ((subKey == "X" && subValue.get() == 7.0) || - (subKey == "Y" && subValue.get() == 8.0) || - (subKey == "Z" && subValue.get() == 9.0) || - (subKey == "U" && subValue.get() == 10.0))) - { - count++; - } - } - } - } - EXPECT_EQ(10, count); - gotControllerDataItem = true; - } - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent("/samples/data_set.xml"); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/" - "WorkOffsetTable[wpo]"); - - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|wpo|G53.1={X=1.0 Y=2.0 Z=3.0} G53.2={X=4.0 Y=5.0 Z=6.0}" - "G53.3={X=7.0 Y=8.0 Z=9 U=10.0}"); - - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Temperature) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotTemperature = false; - handler->m_receive = [&gotTemperature](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" - "Temperature[z_motor_temp]", - topic); - auto jdoc = json::parse(payload); - - auto value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(81.0, value); - gotTemperature = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" - "Temperature[z_motor_temp]"); - - m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|z_motor_temp|81"); - - ASSERT_TRUE(waitFor(5s, [&gotTemperature]() { return gotTemperature; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_LinearLoad) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotLinearLoad = false; - handler->m_receive = [&gotLinearLoad](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]", topic); - auto jdoc = json::parse(payload); - auto value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(50.0, value); - gotLinearLoad = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]"); - - m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|Xload|50"); - ASSERT_TRUE(waitFor(5s, [&gotLinearLoad]() { return gotLinearLoad; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_DynamicCalibration) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotCalibration = false; - handler->m_receive = [this, &gotCalibration](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]", - topic); - auto jdoc = json::parse(payload); - - auto value = jdoc.at("/value"_json_pointer); - ASSERT_TRUE(value.is_array()); - EXPECT_EQ(25, value.size()); - gotCalibration = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]"); - - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|Xts|25|| 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 " - "5119 5119 5118 " - "5118 5117 5117 5119 5119 5118 5118 5118 5118 5118"); - - ASSERT_TRUE(waitFor(5s, [&gotCalibration]() { return gotCalibration; })); -} - -/// @test check if the condition includes the state as the key -TEST_F(MqttSinkTest, mqtt_should_publish_conditions_with_the_state_as_the_key) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotCondition = false; - - handler->m_receive = [&gotCondition](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature", topic); - auto jdoc = json::parse(payload); - EXPECT_EQ("Temperature is too high", jdoc.at("/Fault/value"_json_pointer).get()); - EXPECT_EQ("X111", jdoc.at("/Fault/nativeCode"_json_pointer).get()); - EXPECT_EQ("BAD", jdoc.at("/Fault/nativeSeverity"_json_pointer).get()); - EXPECT_EQ("HIGH", jdoc.at("/Fault/qualifier"_json_pointer).get()); - EXPECT_EQ("TEMPERATURE", jdoc.at("/Fault/type"_json_pointer).get()); - - gotCondition = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent(); - - auto di = m_agentTestHelper->m_agent->getDataItemById("ctmp"); - ASSERT_TRUE(di); - ASSERT_EQ("000/Axes[Axes]/Rotary[C]/Condition/Temperature", di->getTopic()); - - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature"); - - m_agentTestHelper->m_adapter->processData( - "2018-04-27T05:00:26.555666|ctmp|fault|X111|BAD|HIGH|Temperature is too high"); - ASSERT_TRUE(waitFor(5s, [&gotCondition]() { return gotCondition; })); -} diff --git a/test_package/mqtt_sink_test.cpp b/test_package/mqtt_sink_test.cpp index 5aa93846b..e3c63af4c 100644 --- a/test_package/mqtt_sink_test.cpp +++ b/test_package/mqtt_sink_test.cpp @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) using json = nlohmann::json; -class MqttSink2Test : public testing::Test +class MqttSinkTest : public testing::Test { protected: void SetUp() override @@ -62,6 +62,7 @@ class MqttSink2Test : public testing::Test void TearDown() override { const auto agent = m_agentTestHelper->getAgent(); + m_agentTestHelper->m_ioContext.run_for(500ms); if (agent) { m_agentTestHelper->getAgent()->stop(); @@ -184,7 +185,7 @@ class MqttSink2Test : public testing::Test uint16_t m_port {0}; }; -TEST_F(MqttSink2Test, mqtt_sink_flat_formatt_check) +TEST_F(MqttSinkTest, mqtt_sink_flat_formatt_check) { ConfigOptions options {{MqttMaxTopicDepth, 9}, {ProbeTopic, "Device/F/l/a/t/F/o/r/m/a/t"s}}; createServer(options); @@ -198,7 +199,7 @@ TEST_F(MqttSink2Test, mqtt_sink_flat_formatt_check) ASSERT_TRUE(waitFor(10s, [&service]() { return service->isConnected(); })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe) { ConfigOptions options; createServer(options); @@ -237,7 +238,7 @@ TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe) ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Sample) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) { ConfigOptions options; createServer(options); @@ -274,7 +275,7 @@ TEST_F(MqttSink2Test, mqtt_sink_should_publish_Sample) ASSERT_TRUE(waitFor(10s, [&gotSample]() { return gotSample; })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Current) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Current) { ConfigOptions options; createServer(options); @@ -311,7 +312,7 @@ TEST_F(MqttSink2Test, mqtt_sink_should_publish_Current) ASSERT_TRUE(waitFor(1s, [&gotCurrent]() { return gotCurrent; })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_with_uuid_first) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe_with_uuid_first) { ConfigOptions options; createServer(options); @@ -350,7 +351,7 @@ TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_with_uuid_first) ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_no_device_in_format) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe_no_device_in_format) { ConfigOptions options; createServer(options); @@ -389,7 +390,7 @@ TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_no_device_in_format) ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_agent_device) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_agent_device) { ConfigOptions options; createServer(options); From e0d4251f5737e8303428acb9097e8f8ba1871601 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 13 May 2024 13:44:35 -0400 Subject: [PATCH 055/128] Merged in main branch to main-dev --- CMakeLists.txt | 2 +- conanfile.py | 2 +- src/mtconnect/mqtt/mqtt_client_impl.hpp | 1 + src/mtconnect/sink/mqtt_sink/mqtt_service.cpp | 22 ++++++++++--------- src/mtconnect/sink/mqtt_sink/mqtt_service.hpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 4 +++- test_package/mqtt_sink_test.cpp | 15 +++++++++---- 7 files changed, 30 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ea263a17..9f23f2b32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) set(AGENT_VERSION_BUILD 0) -set(AGENT_VERSION_RC "RC2") +set(AGENT_VERSION_RC "RC3") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) diff --git a/conanfile.py b/conanfile.py index 02cd0438a..4c1896b00 100644 --- a/conanfile.py +++ b/conanfile.py @@ -9,7 +9,7 @@ class MTConnectAgentConan(ConanFile): name = "mtconnect_agent" - version = "2.2" + version = "2.3" url = "https://github.com/mtconnect/cppagent.git" license = "Apache License 2.0" settings = "os", "compiler", "arch", "build_type" diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index 8edeedc7b..13ec3ec3e 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -164,6 +164,7 @@ namespace mtconnect { m_connected = false; if (m_handler && m_handler->m_disconnected) m_handler->m_disconnected(shared_from_this()); + if (m_running) { reconnect(); diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp index 7c17edbfd..72fbfd6e4 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp @@ -187,7 +187,7 @@ namespace mtconnect { } } - auto seq = m_sinkContract->getCircularBuffer().getSequence(); + auto seq = publishCurrent(boost::system::error_code {}); for (auto &dev : m_sinkContract->getDevices()) { FilterSet filterSet = filterForDevice(dev); @@ -199,10 +199,8 @@ namespace mtconnect { sampler->observe(seq, [this](const std::string &id) { return m_sinkContract->getDataItemById(id).get(); }); - sampler->handlerCompleted(); + publishSample(sampler); } - - publishCurrent(boost::system::error_code {}); } /// @brief publish sample when observations arrive. @@ -246,18 +244,20 @@ namespace mtconnect { return end; } - void MqttService::publishCurrent(boost::system::error_code ec) + SequenceNumber_t MqttService::publishCurrent(boost::system::error_code ec) { + SequenceNumber_t firstSeq, seq = 0; + if (ec) { LOG(warning) << "Mqtt2Service::publishCurrent: " << ec.message(); - return; + return 0; } if (!m_client->isRunning() || !m_client->isConnected()) { LOG(warning) << "Mqtt2Service::publishCurrent: client stopped"; - return; + return 0; } for (auto &device : m_sinkContract->getDevices()) @@ -266,7 +266,6 @@ namespace mtconnect { LOG(debug) << "Publishing current for: " << topic; ObservationList observations; - SequenceNumber_t firstSeq, seq; auto filterSet = filterForDevice(device); { @@ -290,6 +289,8 @@ namespace mtconnect { m_currentTimer.expires_after(m_currentInterval); m_currentTimer.async_wait(boost::asio::bind_executor( m_strand, boost::bind(&MqttService::publishCurrent, this, _1))); + + return seq; } bool MqttService::publish(observation::ObservationPtr &observation) @@ -327,8 +328,9 @@ namespace mtconnect { LOG(debug) << "Publishing Asset to topic: " << topic; - auto doc = m_jsonPrinter->print(asset); - + asset::AssetList list {asset}; + auto doc = m_printer->printAssets( + m_instanceId, uint32_t(m_sinkContract->getAssetStorage()->getMaxAssets()), 1, list); stringstream buffer; buffer << doc; diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp index 6cba52409..7a6228152 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp @@ -96,7 +96,7 @@ namespace mtconnect { void pubishInitialContent(); /// @brief Publish a current using `CurrentInterval` option. - void publishCurrent(boost::system::error_code ec); + SequenceNumber_t publishCurrent(boost::system::error_code ec); /// @brief publish sample when observations arrive. SequenceNumber_t publishSample(std::shared_ptr sampler); diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 210865470..7026c8ebd 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -544,16 +544,18 @@ namespace mtconnect { auto idHandler = [&](SessionPtr session, RequestPtr request) -> bool { auto asset = request->parameter("assetIds"); + auto pretty = *request->parameter("pretty"); if (asset) { auto pretty = request->parameter("pretty").value_or(false); auto printer = m_sinkContract->getPrinter(acceptFormat(request->m_accepts)); - + list ids; stringstream str(*asset); string id; while (getline(str, id, ';')) ids.emplace_back(id); + respond(session, assetIdsRequest(printer, ids, pretty, request->m_requestId), request->m_requestId); } diff --git a/test_package/mqtt_sink_test.cpp b/test_package/mqtt_sink_test.cpp index e3c63af4c..54d2a27dc 100644 --- a/test_package/mqtt_sink_test.cpp +++ b/test_package/mqtt_sink_test.cpp @@ -62,7 +62,6 @@ class MqttSinkTest : public testing::Test void TearDown() override { const auto agent = m_agentTestHelper->getAgent(); - m_agentTestHelper->m_ioContext.run_for(500ms); if (agent) { m_agentTestHelper->getAgent()->stop(); @@ -249,8 +248,15 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) auto handler = make_unique(); bool gotSample = false; - handler->m_receive = [&gotSample](std::shared_ptr client, const std::string &topic, + bool first = true; + handler->m_receive = [&gotSample, &first](std::shared_ptr client, const std::string &topic, const std::string &payload) { + if (first) + { + first = false; + } + else + { EXPECT_EQ("MTConnect/Sample/000", topic); auto jdoc = json::parse(payload); @@ -258,6 +264,7 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); gotSample = true; + } }; createClient(options, std::move(handler)); @@ -268,8 +275,8 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - ASSERT_FALSE(gotSample); + ASSERT_TRUE(waitFor(60s, [&first]() { return !first; })); + ASSERT_FALSE(first); m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); ASSERT_TRUE(waitFor(10s, [&gotSample]() { return gotSample; })); From ef309136c31d59c88d630897d247926fa904b8eb Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 13 May 2024 13:46:13 -0400 Subject: [PATCH 056/128] Vesion 2.5.0.0 RC 4 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f23f2b32..589c2ab4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) set(AGENT_VERSION_BUILD 0) -set(AGENT_VERSION_RC "RC3") +set(AGENT_VERSION_RC "RC4") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) From 3b2eae01830d72be50e026f7b55df11663526d49 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 15 May 2024 11:08:35 -0400 Subject: [PATCH 057/128] Changed conanfile to 2.5 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 4c1896b00..8145adf80 100644 --- a/conanfile.py +++ b/conanfile.py @@ -9,7 +9,7 @@ class MTConnectAgentConan(ConanFile): name = "mtconnect_agent" - version = "2.3" + version = "2.5" url = "https://github.com/mtconnect/cppagent.git" license = "Apache License 2.0" settings = "os", "compiler", "arch", "build_type" From 7385451e3708b85e246430ff7d185c365f996449 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 21 Jun 2024 11:22:09 -0400 Subject: [PATCH 058/128] Fixed conanfile --- conanfile.py | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/conanfile.py b/conanfile.py index 00fded752..745600d77 100644 --- a/conanfile.py +++ b/conanfile.py @@ -9,6 +9,115 @@ class MTConnectAgentConan(ConanFile): name = "mtconnect_agent" + version = "2.3" + url = "https://github.com/mtconnect/cppagent.git" + license = "Apache License 2.0" + settings = "os", "compiler", "arch", "build_type" + options = { "without_ipv6": [True, False], + "with_ruby": [True, False], + "development" : [True, False], + "shared": [True, False], + "winver": [None, "ANY"], + "with_docs" : [True, False], + "cpack": [True, False], + "agent_prefix": [None, "ANY"], + "fPIC": [True, False], + "cpack_destination": [None, "ANY"], + "cpack_name": [None, "ANY"], + "cpack_generator": [None, "ANY"] + } + + description = "MTConnect reference C++ agent copyright Association for Manufacturing Technology" + + build_policy = "missing" + default_options = { + "without_ipv6": False, + "with_ruby": True, + "development": False, + "shared": False, + "winver": "0x0602", + "with_docs": False, + "cpack": False, + "agent_prefix": None, + "fPIC": True, + "cpack_destination": None, + "cpack_name": None, + "cpack_generator": None, + + "boost*:shared": False, + "boost*:without_python": True, + "boost*:without_test": True, + "boost*:without_graph": True, + "boost*:without_test": True, + "boost*:without_nowide": True, + "boost*:without_fiber": True, + "boost*:without_math": True, + "boost*:without_contract": True, + "boost*:without_serialization": True, + "boost*:without_wave": True, + "boost*:without_graph_parallel": True, + + "libxml2*:shared": False, + "libxml2*:include_utils": False, + "libxml2*:http": False, + "libxml2*:ftp": False, + "libxml2*:iconv": False, + "libxml2*:zlib": False, + + "gtest*:shared": False, + + "openssl*:shared": False, + + "date*:use_system_tz_db": True + } + + exports_sources = "*", "!build", "!test_package/build", "!*~" + exports = "conan/mqtt_cpp/*", "conan/mruby/*" + + def validate(self): + if is_msvc(self) and self.options.shared and self.settings.compiler.runtime != 'dynamic': + raise ConanInvalidConfiguration("Shared can only be built with DLL runtime.") + if "libcxx" in self.settings.compiler.fields and self.settings.compiler.libcxx == "libstdc++": + raise ConanInvalidConfiguration("This package is only compatible with libstdc++11, add -s compiler.libcxx=libstdc++11") + + def layout(self): + self.folders.build_folder_vars = ["options.shared", "settings.arch"] + cmake_layout(self) + + def layout(self): + self.folders.build_folder_vars = ["options.shared", "settings.arch"] + cmake_layout(self) + + def config_options(self): + if is_msvc(self): + self.options.rm_safe("fPIC") + + def tool_requires_version(self, package, version): + self.output.info(f"Checking version of {package} > {version}") + buf = io.StringIO() + command = f"{package} --version" + res = self.run(command, shell=True, stdout=buf) + ver = [0, 0, 0] + if res == 0: + text = buf.getvalue() + self.output.debug(f"{command} returned:\n{text}") + ver = [int(d) for d in re.search(r"\d+\.\d+\.\d+", text).group(0).split('.')] + self.output.info(f"Version of {package} is {ver}") + else: + self.output.info(f"Command: '{command}' returned {res}") + if ver < version: + ver_text = '.'.join([str(x) for x in version]) + self.output.info(f"Old version of {package}, requesting tool {package}/{ver_text}") + self.tool_requires(f"{package}/{ver_text}") + else: + self.output.info(f"Using system version {package}: {ver}") + + def build_requirements(self): + self.tool_requires_version("cmake", [3, 26, 4]) + if self.options.with_docs: + self.tool_requires_version("doxygen", [1, 9, 4]) + + def requirements(self): self.requires("boost/1.85.0", headers=True, libs=True, transitive_headers=True, transitive_libs=True) self.requires("libxml2/2.10.3", headers=True, libs=True, visible=True, transitive_headers=True, transitive_libs=True) self.requires("date/2.4.1", headers=True, libs=True, transitive_headers=True, transitive_libs=True) From 958b7f76a5452855d61e992e6d9bf8b5d7a7381a Mon Sep 17 00:00:00 2001 From: Trais McAllister Date: Sun, 22 Sep 2024 01:01:50 -0400 Subject: [PATCH 059/128] Transpiled observation_validations.hpp --- .../validation/observation_validations.hpp | 337 +++++++----------- 1 file changed, 138 insertions(+), 199 deletions(-) diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index 1f7cb73ef..967220520 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,200 +1,139 @@ Validation ControlledVocabularies { - {"ActiveAxes", {}}, - {"ActuatorState", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"Alarm", {}}, - {"AssetChanged", {}}, - {"AssetRemoved", {}}, - {"Availability", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, - {"AxisCoupling", {{"TANDEM", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}, {"SLAVE", 0}}}, - {"AxisFeedrateOverride", {}}, - {"AxisInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"AxisState", {{"HOME", 0}, {"TRAVEL", 0}, {"PARKED", 0}, {"STOPPED", 0}}}, - {"Block", {}}, - {"BlockCount", {}}, - {"ChuckInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"ChuckState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, - {"Code", {}}, - {"CompositionState", {}}, - {"ControllerMode", - {{"AUTOMATIC", 0}, - {"MANUAL", 0}, - {"MANUAL_DATA_INPUT", 0}, - {"SEMI_AUTOMATIC", 0}, - {"EDIT", 0}, - {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, - {"ControllerModeOverride", {{"ON", 0}, {"OFF", 0}}}, - {"CoupledAxes", {}}, - {"DateCode", {}}, - {"DeviceUuid", {}}, - {"Direction", - {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, - {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, - {"POSITIVE", SCHEMA_VERSION(1, 4)}, - {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, - {"DoorState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, - {"EmergencyStop", {{"ARMED", 0}, {"TRIGGERED", 0}}}, - {"EndOfBar", {{"YES", 0}, {"NO", 0}}}, - {"EquipmentMode", {{"ON", 0}, {"OFF", 0}}}, - {"Execution", - {{"READY", 0}, - {"ACTIVE", 0}, - {"INTERRUPTED", 0}, - {"FEED_HOLD", 0}, - {"STOPPED", 0}, - {"OPTIONAL_STOP", 0}, - {"PROGRAM_STOPPED", 0}, - {"PROGRAM_COMPLETED", 0}, - {"WAIT", 0}, - {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, - {"FunctionalMode", - {{"PRODUCTION", 0}, - {"SETUP", 0}, - {"TEARDOWN", 0}, - {"MAINTENANCE", 0}, - {"PROCESS_DEVELOPMENT", 0}}}, - {"Hardness", {}}, - {"Line", {}}, - {"LineLabel", {}}, - {"LineNumber", {}}, - {"Material", {}}, - {"MaterialLayer", {}}, - {"Message", {}}, - {"OperatorId", {}}, - {"PalletId", {}}, - {"PartCount", {}}, - {"PartDetect", {{"PRESENT", 0}, {"NOT_PRESENT", 0}}}, - {"PartId", {}}, - {"PartNumber", {}}, - {"PathFeedrateOverride", {}}, - {"PathMode", {{"INDEPENDENT", 0}, {"MASTER", 0}, {"SYNCHRONOUS", 0}, {"MIRROR", 0}}}, - {"PowerState", {{"ON", 0}, {"OFF", 0}}}, - {"PowerStatus", {{"ON", SCHEMA_VERSION(1, 1)}, {"OFF", SCHEMA_VERSION(1, 1)}}}, - {"ProcessTime", {}}, - {"Program", {}}, - {"ProgramComment", {}}, - {"ProgramEdit", {{"ACTIVE", 0}, {"READY", 0}, {"NOT_READY", 0}}}, - {"ProgramEditName", {}}, - {"ProgramHeader", {}}, - {"ProgramLocation", {}}, - {"ProgramLocationType", {{"LOCAL", 0}, {"EXTERNAL", 0}}}, - {"ProgramNestLevel", {}}, - {"RotaryMode", {{"SPINDLE", 0}, {"INDEX", 0}, {"CONTOUR", 0}}}, - {"RotaryVelocityOverride", {}}, - {"SerialNumber", {}}, - {"SpindleInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"ToolAssetId", {}}, - {"ToolGroup", {}}, - {"ToolId", {}}, - {"ToolNumber", {}}, - {"ToolOffset", {}}, - {"User", {}}, - {"Variable", {}}, - {"WaitState", - {{"POWERING_UP", 0}, - {"POWERING_DOWN", 0}, - {"PART_LOAD", 0}, - {"PART_UNLOAD", 0}, - {"TOOL_LOAD", 0}, - {"TOOL_UNLOAD", 0}, - {"MATERIAL_LOAD", 0}, - {"MATERIAL_UNLOAD", 0}, - {"SECONDARY_PROCESS", 0}, - {"PAUSING", 0}, - {"RESUMING", 0}}}, - {"Wire", {}}, - {"WorkholdingId", {}}, - {"WorkOffset", {}}, - {"OperatingSystem", {}}, - {"Firmware", {}}, - {"Application", {}}, - {"Library", {}}, - {"Hardware", {}}, - {"Network", {}}, - {"Rotation", {}}, - {"Translation", {}}, - {"ProcessKindId", {}}, - {"PartStatus", {{"PASS", 0}, {"FAIL", 0}}}, - {"AlarmLimit", {}}, - {"ProcessAggregateId", {}}, - {"PartKindId", {}}, - {"AdapterURI", {}}, - {"DeviceRemoved", {}}, - {"DeviceChanged", {}}, - {"SpecificationLimit", {}}, - {"ConnectionStatus", {{"CLOSED", 0}, {"LISTEN", 0}, {"ESTABLISHED", 0}}}, - {"AdapterSoftwareVersion", {}}, - {"SensorAttachment", {}}, - {"ControlLimit", {}}, - {"DeviceAdded", {}}, - {"MTConnectVersion", {}}, - {"ProcessOccurrenceId", {}}, - {"PartGroupId", {}}, - {"PartUniqueId", {}}, - {"ActivationCount", {}}, - {"DeactivationCount", {}}, - {"TransferCount", {}}, - {"LoadCount", {}}, - {"PartProcessingState", - {{"NEEDS_PROCESSING", 0}, - {"IN_PROCESS", 0}, - {"PROCESSING_ENDED", 0}, - {"PROCESSING_ENDED_COMPLETE", 0}, - {"PROCESSING_ENDED_STOPPED", 0}, - {"PROCESSING_ENDED_ABORTED", 0}, - {"PROCESSING_ENDED_LOST", 0}, - {"PROCESSING_ENDED_SKIPPED", 0}, - {"PROCESSING_ENDED_REJECTED", 0}, - {"WAITING_FOR_TRANSIT", 0}, - {"IN_TRANSIT", 0}, - {"TRANSIT_COMPLETE", 0}}}, - {"ProcessState", - {{"INITIALIZING", 0}, - {"READY", 0}, - {"ACTIVE", 0}, - {"COMPLETE", 0}, - {"INTERRUPTED", 0}, - {"ABORTED", 0}}}, - {"ValveState", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, - {"LockState", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, - {"UnloadCount", {}}, - {"CycleCount", {}}, - {"OperatingMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, - {"AssetCount", {}}, - {"MaintenanceList", {}}, - {"FixtureId", {}}, - {"PartCountType", {{"EACH", 0}, {"BATCH", 0}}}, - {"ClockTime", {}}, - {"NetworkPort", {}}, - {"HostName", {}}, - {"LeakDetect", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, - {"BatteryState", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGING", 0}, {"DISCHARGED", 0}}}, - {"FeaturePersisitentId", {}}, - {"SensorState", {}}, - {"ComponentData", {}}, - {"WorkOffsets", {}}, - {"ToolOffsets", {}}, - {"FeatureMeasurement", {}}, - {"CharacteristicPersistentId", {}}, - {"MeasurementType", {}}, - {"MeasurementValue", {}}, - {"MeasurementUnits", {}}, - {"CharacteristicStatus", - {{"PASS", 0}, - {"FAIL", 0}, - {"REWORK", 0}, - {"SYSTEM_ERROR", 0}, - {"INDETERMINATE", 0}, - {"NOT_ANALYZED", 0}, - {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, - {"UNDEFINED", 0}}}, - {"UncertaintyType", {{"COMBINED", 0}, {"MEAN", 0}}}, - {"Uncertainty", {}}, - {"AlarmLimits", {}}, - {"ControlLimits", {}}, - {"SpecificationLimits", {}}, - {"ToolCuttingItem", {}}, - {"LocationAddress", {}}, - {"ActivePowerSource", {}}, - {"LocationNarrative", {}}, - {"Thickness", {}}, - {"LocationSpatialGeographic", {}}}; + {"ActiveAxes",{}}, + {"ActuatorState",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, + {"Alarm",{}}, + {"AssetChanged",{}}, + {"AssetRemoved",{}}, + {"Availability",{{"AVAILABLE", 0}, {"UNAVAILABLE", 0} }}, + {"AxisCoupling",{{"MASTER", 0}, {"SLAVE", 0}, {"SYNCHRONOUS", 0}, {"TANDEM", 0} }}, + {"AxisFeedrateOverride",{}}, + {"AxisInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, + {"AxisState",{{"HOME", 0}, {"PARKED", 0}, {"STOPPED", 0}, {"TRAVEL", 0} }}, + {"Block",{}}, + {"BlockCount",{}}, + {"ChuckInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, + {"ChuckState",{{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0} }}, + {"Code",{}}, + {"CompositionState",{}}, + {"ControllerMode",{{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}, {"EDIT", 0} }}, + {"ControllerModeOverride",{{"OFF", 0}, {"ON", 0} }}, + {"CoupledAxes",{}}, + {"DateCode",{}}, + {"DeviceUuid",{}}, + {"Direction",{{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)} }}, + {"DoorState",{{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0} }}, + {"EmergencyStop",{{"ARMED", 0}, {"TRIGGERED", 0} }}, + {"EndOfBar",{{"NO", 0}, {"YES", 0} }}, + {"EquipmentMode",{{"OFF", 0}, {"ON", 0} }}, + {"Execution",{{"ACTIVE", 0}, {"INTERRUPTED", 0}, {"READY", 0}, {"STOPPED", 0}, {"FEED_HOLD", 0}, {"PROGRAM_COMPLETED", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}, {"PROGRAM_STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"WAIT", 0} }}, + {"FunctionalMode",{{"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}, {"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0} }}, + {"Hardness",{}}, + {"Line",{}}, + {"LineLabel",{}}, + {"LineNumber",{}}, + {"Material",{}}, + {"MaterialLayer",{}}, + {"Message",{}}, + {"OperatorId",{}}, + {"PalletId",{}}, + {"PartCount",{}}, + {"PartDetect",{{"NOT_PRESENT", 0}, {"PRESENT", 0} }}, + {"PartId",{}}, + {"PartNumber",{}}, + {"PathFeedrateOverride",{}}, + {"PathMode",{{"INDEPENDENT", 0}, {"MIRROR", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0} }}, + {"PowerState",{{"OFF", 0}, {"ON", 0} }}, + {"PowerStatus",{{"OFF", SCHEMA_VERSION(1, 1)}, {"ON", SCHEMA_VERSION(1, 1)} }}, + {"ProcessTime",{}}, + {"Program",{}}, + {"ProgramComment",{}}, + {"ProgramEdit",{{"ACTIVE", 0}, {"NOT_READY", 0}, {"READY", 0} }}, + {"ProgramEditName",{}}, + {"ProgramHeader",{}}, + {"ProgramLocation",{}}, + {"ProgramLocationType",{{"EXTERNAL", 0}, {"LOCAL", 0} }}, + {"ProgramNestLevel",{}}, + {"RotaryMode",{{"CONTOUR", 0}, {"INDEX", 0}, {"SPINDLE", 0} }}, + {"RotaryVelocityOverride",{}}, + {"SerialNumber",{}}, + {"SpindleInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, + {"ToolAssetId",{}}, + {"ToolGroup",{}}, + {"ToolId",{}}, + {"ToolNumber",{}}, + {"ToolOffset",{}}, + {"User",{}}, + {"Variable",{}}, + {"WaitState",{{"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"PAUSING", 0}, {"POWERING_DOWN", 0}, {"POWERING_UP", 0}, {"RESUMING", 0}, {"SECONDARY_PROCESS", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0} }}, + {"Wire",{}}, + {"WorkholdingId",{}}, + {"WorkOffset",{}}, + {"OperatingSystem",{}}, + {"Firmware",{}}, + {"Application",{}}, + {"Library",{}}, + {"Hardware",{}}, + {"Network",{}}, + {"Rotation",{}}, + {"Translation",{}}, + {"ProcessKindId",{}}, + {"PartStatus",{{"FAIL", 0}, {"PASS", 0} }}, + {"AlarmLimit",{}}, + {"ProcessAggregateId",{}}, + {"PartKindId",{}}, + {"AdapterURI",{}}, + {"DeviceRemoved",{}}, + {"DeviceChanged",{}}, + {"SpecificationLimit",{}}, + {"ConnectionStatus",{{"CLOSED", 0}, {"ESTABLISHED", 0}, {"LISTEN", 0} }}, + {"AdapterSoftwareVersion",{}}, + {"SensorAttachment",{}}, + {"ControlLimit",{}}, + {"DeviceAdded",{}}, + {"MTConnectVersion",{}}, + {"ProcessOccurrenceId",{}}, + {"PartGroupId",{}}, + {"PartUniqueId",{}}, + {"ActivationCount",{}}, + {"DeactivationCount",{}}, + {"TransferCount",{}}, + {"LoadCount",{}}, + {"PartProcessingState",{{"IN_PROCESS", 0}, {"IN_TRANSIT", 0}, {"NEEDS_PROCESSING", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"TRANSIT_COMPLETE", 0}, {"WAITING_FOR_TRANSIT", 0} }}, + {"ProcessState",{{"ABORTED", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INITIALIZING", 0}, {"INTERRUPTED", 0}, {"READY", 0} }}, + {"ValveState",{{"CLOSED", 0}, {"CLOSING", 0}, {"OPEN", 0}, {"OPENING", 0} }}, + {"LockState",{{"LOCKED", 0}, {"UNLOCKED", 0} }}, + {"UnloadCount",{}}, + {"CycleCount",{}}, + {"OperatingMode",{{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0} }}, + {"AssetCount",{}}, + {"MaintenanceList",{}}, + {"FixtureId",{}}, + {"PartCountType",{{"BATCH", 0}, {"EACH", 0} }}, + {"ClockTime",{}}, + {"NetworkPort",{}}, + {"HostName",{}}, + {"LeakDetect",{{"DETECTED", 0}, {"NOT_DETECTED", 0} }}, + {"BatteryState",{{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGED", 0}, {"DISCHARGING", 0} }}, + {"FeaturePersisitentId",{}}, + {"SensorState",{}}, + {"ComponentData",{}}, + {"WorkOffsets",{}}, + {"ToolOffsets",{}}, + {"FeatureMeasurement",{}}, + {"CharacteristicPersistentId",{}}, + {"MeasurementType",{}}, + {"MeasurementValue",{}}, + {"MeasurementUnits",{}}, + {"CharacteristicStatus",{{"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"FAIL", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"PASS", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"UNDEFINED", 0} }}, + {"UncertaintyType",{{"COMBINED", 0}, {"MEAN", 0} }}, + {"Uncertainty",{}}, + {"AlarmLimits",{}}, + {"ControlLimits",{}}, + {"SpecificationLimits",{}}, + {"ToolCuttingItem",{}}, + {"LocationAddress",{}}, + {"ActivePowerSource",{}}, + {"LocationNarrative",{}}, + {"Thickness",{}}, + {"LocationSpatialGeographic",{}} +}; \ No newline at end of file From ea6b00cc8ee20761cb98c2b21c2f8030cff37d62 Mon Sep 17 00:00:00 2001 From: Trais McAllister Date: Sun, 22 Sep 2024 01:05:38 -0400 Subject: [PATCH 060/128] Update observation_validations.hpp --- .../validation/observation_validations.hpp | 274 +++++++++--------- 1 file changed, 137 insertions(+), 137 deletions(-) diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index 967220520..bc2843f23 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,139 +1,139 @@ Validation ControlledVocabularies { - {"ActiveAxes",{}}, - {"ActuatorState",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, - {"Alarm",{}}, - {"AssetChanged",{}}, - {"AssetRemoved",{}}, - {"Availability",{{"AVAILABLE", 0}, {"UNAVAILABLE", 0} }}, - {"AxisCoupling",{{"MASTER", 0}, {"SLAVE", 0}, {"SYNCHRONOUS", 0}, {"TANDEM", 0} }}, - {"AxisFeedrateOverride",{}}, - {"AxisInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, - {"AxisState",{{"HOME", 0}, {"PARKED", 0}, {"STOPPED", 0}, {"TRAVEL", 0} }}, - {"Block",{}}, - {"BlockCount",{}}, - {"ChuckInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, - {"ChuckState",{{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0} }}, - {"Code",{}}, - {"CompositionState",{}}, - {"ControllerMode",{{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}, {"EDIT", 0} }}, - {"ControllerModeOverride",{{"OFF", 0}, {"ON", 0} }}, - {"CoupledAxes",{}}, - {"DateCode",{}}, - {"DeviceUuid",{}}, - {"Direction",{{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)} }}, - {"DoorState",{{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0} }}, - {"EmergencyStop",{{"ARMED", 0}, {"TRIGGERED", 0} }}, - {"EndOfBar",{{"NO", 0}, {"YES", 0} }}, - {"EquipmentMode",{{"OFF", 0}, {"ON", 0} }}, - {"Execution",{{"ACTIVE", 0}, {"INTERRUPTED", 0}, {"READY", 0}, {"STOPPED", 0}, {"FEED_HOLD", 0}, {"PROGRAM_COMPLETED", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}, {"PROGRAM_STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"WAIT", 0} }}, - {"FunctionalMode",{{"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}, {"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0} }}, - {"Hardness",{}}, - {"Line",{}}, - {"LineLabel",{}}, - {"LineNumber",{}}, - {"Material",{}}, - {"MaterialLayer",{}}, - {"Message",{}}, - {"OperatorId",{}}, - {"PalletId",{}}, - {"PartCount",{}}, - {"PartDetect",{{"NOT_PRESENT", 0}, {"PRESENT", 0} }}, - {"PartId",{}}, - {"PartNumber",{}}, - {"PathFeedrateOverride",{}}, - {"PathMode",{{"INDEPENDENT", 0}, {"MIRROR", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0} }}, - {"PowerState",{{"OFF", 0}, {"ON", 0} }}, - {"PowerStatus",{{"OFF", SCHEMA_VERSION(1, 1)}, {"ON", SCHEMA_VERSION(1, 1)} }}, - {"ProcessTime",{}}, - {"Program",{}}, - {"ProgramComment",{}}, - {"ProgramEdit",{{"ACTIVE", 0}, {"NOT_READY", 0}, {"READY", 0} }}, - {"ProgramEditName",{}}, - {"ProgramHeader",{}}, - {"ProgramLocation",{}}, - {"ProgramLocationType",{{"EXTERNAL", 0}, {"LOCAL", 0} }}, - {"ProgramNestLevel",{}}, - {"RotaryMode",{{"CONTOUR", 0}, {"INDEX", 0}, {"SPINDLE", 0} }}, - {"RotaryVelocityOverride",{}}, - {"SerialNumber",{}}, - {"SpindleInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, - {"ToolAssetId",{}}, - {"ToolGroup",{}}, - {"ToolId",{}}, - {"ToolNumber",{}}, - {"ToolOffset",{}}, - {"User",{}}, - {"Variable",{}}, - {"WaitState",{{"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"PAUSING", 0}, {"POWERING_DOWN", 0}, {"POWERING_UP", 0}, {"RESUMING", 0}, {"SECONDARY_PROCESS", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0} }}, - {"Wire",{}}, - {"WorkholdingId",{}}, - {"WorkOffset",{}}, - {"OperatingSystem",{}}, - {"Firmware",{}}, - {"Application",{}}, - {"Library",{}}, - {"Hardware",{}}, - {"Network",{}}, - {"Rotation",{}}, - {"Translation",{}}, - {"ProcessKindId",{}}, - {"PartStatus",{{"FAIL", 0}, {"PASS", 0} }}, - {"AlarmLimit",{}}, - {"ProcessAggregateId",{}}, - {"PartKindId",{}}, - {"AdapterURI",{}}, - {"DeviceRemoved",{}}, - {"DeviceChanged",{}}, - {"SpecificationLimit",{}}, - {"ConnectionStatus",{{"CLOSED", 0}, {"ESTABLISHED", 0}, {"LISTEN", 0} }}, - {"AdapterSoftwareVersion",{}}, - {"SensorAttachment",{}}, - {"ControlLimit",{}}, - {"DeviceAdded",{}}, - {"MTConnectVersion",{}}, - {"ProcessOccurrenceId",{}}, - {"PartGroupId",{}}, - {"PartUniqueId",{}}, - {"ActivationCount",{}}, - {"DeactivationCount",{}}, - {"TransferCount",{}}, - {"LoadCount",{}}, - {"PartProcessingState",{{"IN_PROCESS", 0}, {"IN_TRANSIT", 0}, {"NEEDS_PROCESSING", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"TRANSIT_COMPLETE", 0}, {"WAITING_FOR_TRANSIT", 0} }}, - {"ProcessState",{{"ABORTED", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INITIALIZING", 0}, {"INTERRUPTED", 0}, {"READY", 0} }}, - {"ValveState",{{"CLOSED", 0}, {"CLOSING", 0}, {"OPEN", 0}, {"OPENING", 0} }}, - {"LockState",{{"LOCKED", 0}, {"UNLOCKED", 0} }}, - {"UnloadCount",{}}, - {"CycleCount",{}}, - {"OperatingMode",{{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0} }}, - {"AssetCount",{}}, - {"MaintenanceList",{}}, - {"FixtureId",{}}, - {"PartCountType",{{"BATCH", 0}, {"EACH", 0} }}, - {"ClockTime",{}}, - {"NetworkPort",{}}, - {"HostName",{}}, - {"LeakDetect",{{"DETECTED", 0}, {"NOT_DETECTED", 0} }}, - {"BatteryState",{{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGED", 0}, {"DISCHARGING", 0} }}, - {"FeaturePersisitentId",{}}, - {"SensorState",{}}, - {"ComponentData",{}}, - {"WorkOffsets",{}}, - {"ToolOffsets",{}}, - {"FeatureMeasurement",{}}, - {"CharacteristicPersistentId",{}}, - {"MeasurementType",{}}, - {"MeasurementValue",{}}, - {"MeasurementUnits",{}}, - {"CharacteristicStatus",{{"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"FAIL", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"PASS", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"UNDEFINED", 0} }}, - {"UncertaintyType",{{"COMBINED", 0}, {"MEAN", 0} }}, - {"Uncertainty",{}}, - {"AlarmLimits",{}}, - {"ControlLimits",{}}, - {"SpecificationLimits",{}}, - {"ToolCuttingItem",{}}, - {"LocationAddress",{}}, - {"ActivePowerSource",{}}, - {"LocationNarrative",{}}, - {"Thickness",{}}, - {"LocationSpatialGeographic",{}} + {"ActiveAxes", {}}, + {"ActuatorState", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"Alarm", {}}, + {"AssetChanged", {}}, + {"AssetRemoved", {}}, + {"Availability", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, + {"AxisCoupling", {{"MASTER", 0}, {"SLAVE", 0}, {"SYNCHRONOUS", 0}, {"TANDEM", 0}}}, + {"AxisFeedrateOverride", {}}, + {"AxisInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"AxisState", {{"HOME", 0}, {"PARKED", 0}, {"STOPPED", 0}, {"TRAVEL", 0}}}, + {"Block", {}}, + {"BlockCount", {}}, + {"ChuckInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ChuckState", {{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0}}}, + {"Code", {}}, + {"CompositionState", {}}, + {"ControllerMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}, {"EDIT", 0}}}, + {"ControllerModeOverride", {{"OFF", 0}, {"ON", 0}}}, + {"CoupledAxes", {}}, + {"DateCode", {}}, + {"DeviceUuid", {}}, + {"Direction", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}}}, + {"DoorState", {{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0}}}, + {"EmergencyStop", {{"ARMED", 0}, {"TRIGGERED", 0}}}, + {"EndOfBar", {{"NO", 0}, {"YES", 0}}}, + {"EquipmentMode", {{"OFF", 0}, {"ON", 0}}}, + {"Execution", {{"ACTIVE", 0}, {"INTERRUPTED", 0}, {"READY", 0}, {"STOPPED", 0}, {"FEED_HOLD", 0}, {"PROGRAM_COMPLETED", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}, {"PROGRAM_STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"WAIT", 0}}}, + {"FunctionalMode", {{"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}, {"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}}}, + {"Hardness", {}}, + {"Line", {}}, + {"LineLabel", {}}, + {"LineNumber", {}}, + {"Material", {}}, + {"MaterialLayer", {}}, + {"Message", {}}, + {"OperatorId", {}}, + {"PalletId", {}}, + {"PartCount", {}}, + {"PartDetect", {{"NOT_PRESENT", 0}, {"PRESENT", 0}}}, + {"PartId", {}}, + {"PartNumber", {}}, + {"PathFeedrateOverride", {}}, + {"PathMode", {{"INDEPENDENT", 0}, {"MIRROR", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}}}, + {"PowerState", {{"OFF", 0}, {"ON", 0}}}, + {"PowerStatus", {{"OFF", SCHEMA_VERSION(1, 1)}, {"ON", SCHEMA_VERSION(1, 1)}}}, + {"ProcessTime", {}}, + {"Program", {}}, + {"ProgramComment", {}}, + {"ProgramEdit", {{"ACTIVE", 0}, {"NOT_READY", 0}, {"READY", 0}}}, + {"ProgramEditName", {}}, + {"ProgramHeader", {}}, + {"ProgramLocation", {}}, + {"ProgramLocationType", {{"EXTERNAL", 0}, {"LOCAL", 0}}}, + {"ProgramNestLevel", {}}, + {"RotaryMode", {{"CONTOUR", 0}, {"INDEX", 0}, {"SPINDLE", 0}}}, + {"RotaryVelocityOverride", {}}, + {"SerialNumber", {}}, + {"SpindleInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ToolAssetId", {}}, + {"ToolGroup", {}}, + {"ToolId", {}}, + {"ToolNumber", {}}, + {"ToolOffset", {}}, + {"User", {}}, + {"Variable", {}}, + {"WaitState", {{"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"PAUSING", 0}, {"POWERING_DOWN", 0}, {"POWERING_UP", 0}, {"RESUMING", 0}, {"SECONDARY_PROCESS", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}}}, + {"Wire", {}}, + {"WorkholdingId", {}}, + {"WorkOffset", {}}, + {"OperatingSystem", {}}, + {"Firmware", {}}, + {"Application", {}}, + {"Library", {}}, + {"Hardware", {}}, + {"Network", {}}, + {"Rotation", {}}, + {"Translation", {}}, + {"ProcessKindId", {}}, + {"PartStatus", {{"FAIL", 0}, {"PASS", 0}}}, + {"AlarmLimit", {}}, + {"ProcessAggregateId", {}}, + {"PartKindId", {}}, + {"AdapterURI", {}}, + {"DeviceRemoved", {}}, + {"DeviceChanged", {}}, + {"SpecificationLimit", {}}, + {"ConnectionStatus", {{"CLOSED", 0}, {"ESTABLISHED", 0}, {"LISTEN", 0}}}, + {"AdapterSoftwareVersion", {}}, + {"SensorAttachment", {}}, + {"ControlLimit", {}}, + {"DeviceAdded", {}}, + {"MTConnectVersion", {}}, + {"ProcessOccurrenceId", {}}, + {"PartGroupId", {}}, + {"PartUniqueId", {}}, + {"ActivationCount", {}}, + {"DeactivationCount", {}}, + {"TransferCount", {}}, + {"LoadCount", {}}, + {"PartProcessingState", {{"IN_PROCESS", 0}, {"IN_TRANSIT", 0}, {"NEEDS_PROCESSING", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"TRANSIT_COMPLETE", 0}, {"WAITING_FOR_TRANSIT", 0}}}, + {"ProcessState", {{"ABORTED", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INITIALIZING", 0}, {"INTERRUPTED", 0}, {"READY", 0}}}, + {"ValveState", {{"CLOSED", 0}, {"CLOSING", 0}, {"OPEN", 0}, {"OPENING", 0}}}, + {"LockState", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, + {"UnloadCount", {}}, + {"CycleCount", {}}, + {"OperatingMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, + {"AssetCount", {}}, + {"MaintenanceList", {}}, + {"FixtureId", {}}, + {"PartCountType", {{"BATCH", 0}, {"EACH", 0}}}, + {"ClockTime", {}}, + {"NetworkPort", {}}, + {"HostName", {}}, + {"LeakDetect", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, + {"BatteryState", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGED", 0}, {"DISCHARGING", 0}}}, + {"FeaturePersisitentId", {}}, + {"SensorState", {}}, + {"ComponentData", {}}, + {"WorkOffsets", {}}, + {"ToolOffsets", {}}, + {"FeatureMeasurement", {}}, + {"CharacteristicPersistentId", {}}, + {"MeasurementType", {}}, + {"MeasurementValue", {}}, + {"MeasurementUnits", {}}, + {"CharacteristicStatus", {{"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"FAIL", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"PASS", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"UNDEFINED", 0}}}, + {"UncertaintyType", {{"COMBINED", 0}, {"MEAN", 0}}}, + {"Uncertainty", {}}, + {"AlarmLimits", {}}, + {"ControlLimits", {}}, + {"SpecificationLimits", {}}, + {"ToolCuttingItem", {}}, + {"LocationAddress", {}}, + {"ActivePowerSource", {}}, + {"LocationNarrative", {}}, + {"Thickness", {}}, + {"LocationSpatialGeographic", {}} }; \ No newline at end of file From 8970926da6e82204befa13d35731b8b6352ecfb5 Mon Sep 17 00:00:00 2001 From: Trais McAllister Date: Wed, 25 Sep 2024 10:29:42 -0400 Subject: [PATCH 061/128] Update observation_validations.hpp - Changed Deprecated Value to Tuple --- .../validation/observation_validations.hpp | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index bc2843f23..0fbb4b078 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,32 +1,32 @@ Validation ControlledVocabularies { {"ActiveAxes", {}}, - {"ActuatorState", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ActuatorState", {{"ACTIVE", { SCHEMA_VERSION(1, 2), 0} }, {"INACTIVE", { SCHEMA_VERSION(1, 2), 0} }}}, {"Alarm", {}}, {"AssetChanged", {}}, {"AssetRemoved", {}}, - {"Availability", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, - {"AxisCoupling", {{"MASTER", 0}, {"SLAVE", 0}, {"SYNCHRONOUS", 0}, {"TANDEM", 0}}}, + {"Availability", {{"AVAILABLE", { SCHEMA_VERSION(1, 1), 0} }, {"UNAVAILABLE", { SCHEMA_VERSION(1, 1), 0} }}}, + {"AxisCoupling", {{"MASTER", { SCHEMA_VERSION(1, 1), 0} }, {"SLAVE", { SCHEMA_VERSION(1, 1), 0} }, {"SYNCHRONOUS", { SCHEMA_VERSION(1, 1), 0} }, {"TANDEM", { SCHEMA_VERSION(1, 1), 0} }}}, {"AxisFeedrateOverride", {}}, - {"AxisInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"AxisState", {{"HOME", 0}, {"PARKED", 0}, {"STOPPED", 0}, {"TRAVEL", 0}}}, + {"AxisInterlock", {{"ACTIVE", { SCHEMA_VERSION(1, 3), 0} }, {"INACTIVE", { SCHEMA_VERSION(1, 3), 0} }}}, + {"AxisState", {{"HOME", { SCHEMA_VERSION(1, 3), 0} }, {"PARKED", { SCHEMA_VERSION(1, 3), 0} }, {"STOPPED", { SCHEMA_VERSION(1, 3), 0} }, {"TRAVEL", { SCHEMA_VERSION(1, 3), 0} }}}, {"Block", {}}, {"BlockCount", {}}, - {"ChuckInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"ChuckState", {{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0}}}, + {"ChuckInterlock", {{"ACTIVE", { SCHEMA_VERSION(1, 3), 0} }, {"INACTIVE", { SCHEMA_VERSION(1, 3), 0} }}}, + {"ChuckState", {{"CLOSED", { SCHEMA_VERSION(1, 3), 0} }, {"OPEN", { SCHEMA_VERSION(1, 3), 0} }, {"UNLATCHED", { SCHEMA_VERSION(1, 3), 0} }}}, {"Code", {}}, {"CompositionState", {}}, - {"ControllerMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}, {"EDIT", 0}}}, - {"ControllerModeOverride", {{"OFF", 0}, {"ON", 0}}}, + {"ControllerMode", {{"AUTOMATIC", { SCHEMA_VERSION(1, 0), 0} }, {"MANUAL", { SCHEMA_VERSION(1, 0), 0} }, {"MANUAL_DATA_INPUT", { SCHEMA_VERSION(1, 0), 0} }, {"SEMI_AUTOMATIC", { SCHEMA_VERSION(1, 1), 0} }, {"FEED_HOLD", { SCHEMA_VERSION(1, 2), SCHEMA_VERSION(1, 3)} }, {"EDIT", { SCHEMA_VERSION(1, 3), 0} }}}, + {"ControllerModeOverride", {{"OFF", { SCHEMA_VERSION(1, 4), 0} }, {"ON", { SCHEMA_VERSION(1, 4), 0} }}}, {"CoupledAxes", {}}, {"DateCode", {}}, {"DeviceUuid", {}}, - {"Direction", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}}}, - {"DoorState", {{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0}}}, - {"EmergencyStop", {{"ARMED", 0}, {"TRIGGERED", 0}}}, - {"EndOfBar", {{"NO", 0}, {"YES", 0}}}, - {"EquipmentMode", {{"OFF", 0}, {"ON", 0}}}, - {"Execution", {{"ACTIVE", 0}, {"INTERRUPTED", 0}, {"READY", 0}, {"STOPPED", 0}, {"FEED_HOLD", 0}, {"PROGRAM_COMPLETED", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}, {"PROGRAM_STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"WAIT", 0}}}, - {"FunctionalMode", {{"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}, {"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}}}, + {"Direction", {{"CLOCKWISE", { SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 4)} }, {"COUNTER_CLOCKWISE", { SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 4)} }, {"NEGATIVE", { SCHEMA_VERSION(1, 2), SCHEMA_VERSION(1, 4)} }, {"POSITIVE", { SCHEMA_VERSION(1, 2), SCHEMA_VERSION(1, 4)} }}}, + {"DoorState", {{"CLOSED", { SCHEMA_VERSION(1, 1), 0} }, {"OPEN", { SCHEMA_VERSION(1, 1), 0} }, {"UNLATCHED", { SCHEMA_VERSION(1, 2), 0} }}}, + {"EmergencyStop", {{"ARMED", { SCHEMA_VERSION(1, 1), 0} }, {"TRIGGERED", { SCHEMA_VERSION(1, 1), 0} }}}, + {"EndOfBar", {{"NO", { SCHEMA_VERSION(1, 3), 0} }, {"YES", { SCHEMA_VERSION(1, 3), 0} }}}, + {"EquipmentMode", {{"OFF", { SCHEMA_VERSION(1, 4), 0} }, {"ON", { SCHEMA_VERSION(1, 4), 0} }}}, + {"Execution", {{"ACTIVE", { SCHEMA_VERSION(1, 0), 0} }, {"INTERRUPTED", { SCHEMA_VERSION(1, 0), 0} }, {"READY", { SCHEMA_VERSION(1, 0), 0} }, {"STOPPED", { SCHEMA_VERSION(1, 0), 0} }, {"FEED_HOLD", { SCHEMA_VERSION(1, 3), 0} }, {"PROGRAM_COMPLETED", { SCHEMA_VERSION(1, 3), 0} }, {"PROGRAM_OPTIONAL_STOP", { SCHEMA_VERSION(1, 3), SCHEMA_VERSION(1, 4)} }, {"PROGRAM_STOPPED", { SCHEMA_VERSION(1, 3), 0} }, {"OPTIONAL_STOP", { SCHEMA_VERSION(1, 4), 0} }, {"WAIT", { SCHEMA_VERSION(1, 5), 0} }}}, + {"FunctionalMode", {{"MAINTENANCE", { SCHEMA_VERSION(1, 3), 0} }, {"PROCESS_DEVELOPMENT", { SCHEMA_VERSION(1, 3), 0} }, {"PRODUCTION", { SCHEMA_VERSION(1, 3), 0} }, {"SETUP", { SCHEMA_VERSION(1, 3), 0} }, {"TEARDOWN", { SCHEMA_VERSION(1, 3), 0} }}}, {"Hardness", {}}, {"Line", {}}, {"LineLabel", {}}, @@ -37,26 +37,26 @@ Validation ControlledVocabularies { {"OperatorId", {}}, {"PalletId", {}}, {"PartCount", {}}, - {"PartDetect", {{"NOT_PRESENT", 0}, {"PRESENT", 0}}}, + {"PartDetect", {{"NOT_PRESENT", { SCHEMA_VERSION(1, 5), 0} }, {"PRESENT", { SCHEMA_VERSION(1, 5), 0} }}}, {"PartId", {}}, {"PartNumber", {}}, {"PathFeedrateOverride", {}}, - {"PathMode", {{"INDEPENDENT", 0}, {"MIRROR", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}}}, - {"PowerState", {{"OFF", 0}, {"ON", 0}}}, - {"PowerStatus", {{"OFF", SCHEMA_VERSION(1, 1)}, {"ON", SCHEMA_VERSION(1, 1)}}}, + {"PathMode", {{"INDEPENDENT", { SCHEMA_VERSION(1, 1), 0} }, {"MIRROR", { SCHEMA_VERSION(1, 1), 0} }, {"SYNCHRONOUS", { SCHEMA_VERSION(1, 1), 0} }, {"MASTER", { SCHEMA_VERSION(1, 2), 0} }}}, + {"PowerState", {{"OFF", { SCHEMA_VERSION(1, 1), 0} }, {"ON", { SCHEMA_VERSION(1, 1), 0} }}}, + {"PowerStatus", {{"OFF", { SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 1)} }, {"ON", { SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 1)} }}}, {"ProcessTime", {}}, {"Program", {}}, {"ProgramComment", {}}, - {"ProgramEdit", {{"ACTIVE", 0}, {"NOT_READY", 0}, {"READY", 0}}}, + {"ProgramEdit", {{"ACTIVE", { SCHEMA_VERSION(1, 3), 0} }, {"NOT_READY", { SCHEMA_VERSION(1, 3), 0} }, {"READY", { SCHEMA_VERSION(1, 3), 0} }}}, {"ProgramEditName", {}}, {"ProgramHeader", {}}, {"ProgramLocation", {}}, - {"ProgramLocationType", {{"EXTERNAL", 0}, {"LOCAL", 0}}}, + {"ProgramLocationType", {{"EXTERNAL", { SCHEMA_VERSION(1, 5), 0} }, {"LOCAL", { SCHEMA_VERSION(1, 5), 0} }}}, {"ProgramNestLevel", {}}, - {"RotaryMode", {{"CONTOUR", 0}, {"INDEX", 0}, {"SPINDLE", 0}}}, + {"RotaryMode", {{"CONTOUR", { SCHEMA_VERSION(1, 1), 0} }, {"INDEX", { SCHEMA_VERSION(1, 1), 0} }, {"SPINDLE", { SCHEMA_VERSION(1, 1), 0} }}}, {"RotaryVelocityOverride", {}}, {"SerialNumber", {}}, - {"SpindleInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"SpindleInterlock", {{"ACTIVE", { SCHEMA_VERSION(1, 3), 0} }, {"INACTIVE", { SCHEMA_VERSION(1, 3), 0} }}}, {"ToolAssetId", {}}, {"ToolGroup", {}}, {"ToolId", {}}, @@ -64,7 +64,7 @@ Validation ControlledVocabularies { {"ToolOffset", {}}, {"User", {}}, {"Variable", {}}, - {"WaitState", {{"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"PAUSING", 0}, {"POWERING_DOWN", 0}, {"POWERING_UP", 0}, {"RESUMING", 0}, {"SECONDARY_PROCESS", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}}}, + {"WaitState", {{"MATERIAL_LOAD", { SCHEMA_VERSION(1, 5), 0} }, {"MATERIAL_UNLOAD", { SCHEMA_VERSION(1, 5), 0} }, {"PART_LOAD", { SCHEMA_VERSION(1, 5), 0} }, {"PART_UNLOAD", { SCHEMA_VERSION(1, 5), 0} }, {"PAUSING", { SCHEMA_VERSION(1, 5), 0} }, {"POWERING_DOWN", { SCHEMA_VERSION(1, 5), 0} }, {"POWERING_UP", { SCHEMA_VERSION(1, 5), 0} }, {"RESUMING", { SCHEMA_VERSION(1, 5), 0} }, {"SECONDARY_PROCESS", { SCHEMA_VERSION(1, 5), 0} }, {"TOOL_LOAD", { SCHEMA_VERSION(1, 5), 0} }, {"TOOL_UNLOAD", { SCHEMA_VERSION(1, 5), 0} }}}, {"Wire", {}}, {"WorkholdingId", {}}, {"WorkOffset", {}}, @@ -77,7 +77,7 @@ Validation ControlledVocabularies { {"Rotation", {}}, {"Translation", {}}, {"ProcessKindId", {}}, - {"PartStatus", {{"FAIL", 0}, {"PASS", 0}}}, + {"PartStatus", {{"FAIL", { SCHEMA_VERSION(1, 7), 0} }, {"PASS", { SCHEMA_VERSION(1, 7), 0} }}}, {"AlarmLimit", {}}, {"ProcessAggregateId", {}}, {"PartKindId", {}}, @@ -85,7 +85,7 @@ Validation ControlledVocabularies { {"DeviceRemoved", {}}, {"DeviceChanged", {}}, {"SpecificationLimit", {}}, - {"ConnectionStatus", {{"CLOSED", 0}, {"ESTABLISHED", 0}, {"LISTEN", 0}}}, + {"ConnectionStatus", {{"CLOSED", { SCHEMA_VERSION(1, 7), 0} }, {"ESTABLISHED", { SCHEMA_VERSION(1, 7), 0} }, {"LISTEN", { SCHEMA_VERSION(1, 7), 0} }}}, {"AdapterSoftwareVersion", {}}, {"SensorAttachment", {}}, {"ControlLimit", {}}, @@ -98,22 +98,22 @@ Validation ControlledVocabularies { {"DeactivationCount", {}}, {"TransferCount", {}}, {"LoadCount", {}}, - {"PartProcessingState", {{"IN_PROCESS", 0}, {"IN_TRANSIT", 0}, {"NEEDS_PROCESSING", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"TRANSIT_COMPLETE", 0}, {"WAITING_FOR_TRANSIT", 0}}}, - {"ProcessState", {{"ABORTED", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INITIALIZING", 0}, {"INTERRUPTED", 0}, {"READY", 0}}}, - {"ValveState", {{"CLOSED", 0}, {"CLOSING", 0}, {"OPEN", 0}, {"OPENING", 0}}}, - {"LockState", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, + {"PartProcessingState", {{"IN_PROCESS", { SCHEMA_VERSION(1, 8), 0} }, {"IN_TRANSIT", { SCHEMA_VERSION(1, 8), 0} }, {"NEEDS_PROCESSING", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_ABORTED", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_COMPLETE", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_LOST", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_REJECTED", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_SKIPPED", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_STOPPED", { SCHEMA_VERSION(1, 8), 0} }, {"TRANSIT_COMPLETE", { SCHEMA_VERSION(1, 8), 0} }, {"WAITING_FOR_TRANSIT", { SCHEMA_VERSION(1, 8), 0} }}}, + {"ProcessState", {{"ABORTED", { SCHEMA_VERSION(1, 8), 0} }, {"ACTIVE", { SCHEMA_VERSION(1, 8), 0} }, {"COMPLETE", { SCHEMA_VERSION(1, 8), 0} }, {"INITIALIZING", { SCHEMA_VERSION(1, 8), 0} }, {"INTERRUPTED", { SCHEMA_VERSION(1, 8), 0} }, {"READY", { SCHEMA_VERSION(1, 8), 0} }}}, + {"ValveState", {{"CLOSED", { SCHEMA_VERSION(1, 8), 0} }, {"CLOSING", { SCHEMA_VERSION(1, 8), 0} }, {"OPEN", { SCHEMA_VERSION(1, 8), 0} }, {"OPENING", { SCHEMA_VERSION(1, 8), 0} }}}, + {"LockState", {{"LOCKED", { SCHEMA_VERSION(1, 8), 0} }, {"UNLOCKED", { SCHEMA_VERSION(1, 8), 0} }}}, {"UnloadCount", {}}, {"CycleCount", {}}, - {"OperatingMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, + {"OperatingMode", {{"AUTOMATIC", { SCHEMA_VERSION(2, 0), 0} }, {"MANUAL", { SCHEMA_VERSION(2, 0), 0} }, {"SEMI_AUTOMATIC", { SCHEMA_VERSION(2, 0), 0} }}}, {"AssetCount", {}}, {"MaintenanceList", {}}, {"FixtureId", {}}, - {"PartCountType", {{"BATCH", 0}, {"EACH", 0}}}, + {"PartCountType", {{"BATCH", { SCHEMA_VERSION(2, 0), 0} }, {"EACH", { SCHEMA_VERSION(2, 0), 0} }}}, {"ClockTime", {}}, {"NetworkPort", {}}, {"HostName", {}}, - {"LeakDetect", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, - {"BatteryState", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGED", 0}, {"DISCHARGING", 0}}}, + {"LeakDetect", {{"DETECTED", { SCHEMA_VERSION(2, 1), 0} }, {"NOT_DETECTED", { SCHEMA_VERSION(2, 1), 0} }}}, + {"BatteryState", {{"CHARGED", { SCHEMA_VERSION(2, 1), 0} }, {"CHARGING", { SCHEMA_VERSION(2, 1), 0} }, {"DISCHARGED", { SCHEMA_VERSION(2, 1), 0} }, {"DISCHARGING", { SCHEMA_VERSION(2, 1), 0} }}}, {"FeaturePersisitentId", {}}, {"SensorState", {}}, {"ComponentData", {}}, @@ -124,8 +124,8 @@ Validation ControlledVocabularies { {"MeasurementType", {}}, {"MeasurementValue", {}}, {"MeasurementUnits", {}}, - {"CharacteristicStatus", {{"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"FAIL", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"PASS", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"UNDEFINED", 0}}}, - {"UncertaintyType", {{"COMBINED", 0}, {"MEAN", 0}}}, + {"CharacteristicStatus", {{"BASIC_OR_THEORETIC_EXACT_DIMENSION", { SCHEMA_VERSION(2, 2), 0} }, {"FAIL", { SCHEMA_VERSION(2, 2), 0} }, {"INDETERMINATE", { SCHEMA_VERSION(2, 2), 0} }, {"NOT_ANALYZED", { SCHEMA_VERSION(2, 2), 0} }, {"PASS", { SCHEMA_VERSION(2, 2), 0} }, {"REWORK", { SCHEMA_VERSION(2, 2), 0} }, {"SYSTEM_ERROR", { SCHEMA_VERSION(2, 2), 0} }, {"UNDEFINED", { SCHEMA_VERSION(2, 2), 0} }}}, + {"UncertaintyType", {{"COMBINED", { SCHEMA_VERSION(2, 2), 0} }, {"MEAN", { SCHEMA_VERSION(2, 2), 0} }}}, {"Uncertainty", {}}, {"AlarmLimits", {}}, {"ControlLimits", {}}, From 5d289703dbbed5bf3b5e4dec33083f808a0fad60 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Tue, 2 Apr 2024 10:35:30 -0400 Subject: [PATCH 062/128] Started websocket support --- docker/ubuntu/Dockerfile | 2 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docker/ubuntu/Dockerfile b/docker/ubuntu/Dockerfile index 69d187ae7..7372a5466 100644 --- a/docker/ubuntu/Dockerfile +++ b/docker/ubuntu/Dockerfile @@ -63,7 +63,7 @@ RUN apt-get update \ rake \ ruby \ && rm -rf /var/lib/apt/lists/* \ - && pip install conan + && pip install conan # make an agent directory and cd into it WORKDIR /root/agent diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index 93aae58f7..5faa2931e 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -44,6 +44,7 @@ namespace mtconnect::sink::rest_sink { namespace algo = boost::algorithm; namespace sys = boost::system; namespace ssl = boost::asio::ssl; + namespace ws = boost::beast::websocket; using namespace std; using std::placeholders::_1; @@ -196,7 +197,7 @@ namespace mtconnect::sink::rest_sink { auto &msg = m_parser->get(); const auto &remote = beast::get_lowest_layer(derived().stream()).socket().remote_endpoint(); - + // Check for put, post, or delete if (msg.method() != http::verb::get) { @@ -242,6 +243,12 @@ namespace mtconnect::sink::rest_sink { LOG(info) << "ReST Request: From [" << m_request->m_foreignIp << ':' << remote.port() << "]: " << msg.method() << " " << msg.target(); + + // Check if this is a websocket upgrade request. If so, begin a websocket session. + if (ws::is_upgrade(msg)) + { + LOG(debug) << "Upgrading to websocket request"; + } if (!m_dispatch(shared_ptr(), m_request)) { From 6ea1d387ac191c4a2c7768cc479e91c3a081c4ba Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 8 Apr 2024 13:52:13 -0400 Subject: [PATCH 063/128] checkpoint with initial parsing of json --- agent_lib/CMakeLists.txt | 1 + src/mtconnect/sink/rest_sink/request.hpp | 1 + src/mtconnect/sink/rest_sink/session_impl.cpp | 32 +- src/mtconnect/sink/rest_sink/session_impl.hpp | 14 +- .../sink/rest_sink/websocket_session.hpp | 293 ++++++++++++++++++ 5 files changed, 338 insertions(+), 3 deletions(-) create mode 100644 src/mtconnect/sink/rest_sink/websocket_session.hpp diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index 454608561..93d2d9a6e 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -264,6 +264,7 @@ set(AGENT_SOURCES "${SOURCE_DIR}/sink/rest_sink/session.hpp" "${SOURCE_DIR}/sink/rest_sink/session_impl.hpp" "${SOURCE_DIR}/sink/rest_sink/tls_dector.hpp" + "${SOURCE_DIR}/sink/rest_sink/websocket_session.hpp" # src/sink/rest_sink SOURCE_FILES_ONLY diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index f62f37dbe..5271c791c 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -67,6 +67,7 @@ namespace mtconnect::sink::rest_sink { uint16_t m_foreignPort; ///< The requestors Port QueryMap m_query; ///< The parsed query parameters ParameterMap m_parameters; ///< The parsed path parameters + bool m_parsed { false }; ///< Flag the request as parsed /// @brief Find a parameter by type /// @tparam T the type of the parameter diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index 5faa2931e..2ddd38e33 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -34,6 +34,7 @@ #include "request.hpp" #include "response.hpp" #include "tls_dector.hpp" +#include "websocket_session.hpp" namespace mtconnect::sink::rest_sink { namespace beast = boost::beast; // from @@ -248,9 +249,9 @@ namespace mtconnect::sink::rest_sink { if (ws::is_upgrade(msg)) { LOG(debug) << "Upgrading to websocket request"; + upgrade(std::move(msg)); } - - if (!m_dispatch(shared_ptr(), m_request)) + else if (!m_dispatch(shared_ptr(), m_request)) { ostringstream txt; txt << "Failed to find handler for " << msg.method() << " " << msg.target(); @@ -468,6 +469,16 @@ namespace mtconnect::sink::rest_sink { writeResponse(std::move(response)); } } + + SessionPtr HttpSession::upgradeToWebsocket(RequestMessage &&msg) + { + return std::make_shared(std::move(m_stream), + std::move(m_request), + std::move(msg), + m_dispatch, + m_errorFunction); + } + /// @brief A secure https session class HttpsSession : public SessionImpl @@ -525,6 +536,16 @@ namespace mtconnect::sink::rest_sink { m_stream.async_shutdown(beast::bind_front_handler(&HttpsSession::shutdown, shared_ptr())); } } + + /// @brief Upgrade the current connection to a websocket connection. + SessionPtr upgradeToWebsocket(RequestMessage &&msg) + { + return std::make_shared(std::move(m_stream), + std::move(m_request), + std::move(msg), + m_dispatch, + m_errorFunction); + } protected: void handshake(beast::error_code ec, size_t bytes_used) @@ -548,6 +569,13 @@ namespace mtconnect::sink::rest_sink { beast::ssl_stream m_stream; bool m_closing {false}; }; + + template + void SessionImpl::upgrade(RequestMessage &&msg) + { + LOG(debug) << "Upgrading session to websockets"; + derived().upgradeToWebsocket(std::move(msg))->run(); + } void TlsDector::run() { diff --git a/src/mtconnect/sink/rest_sink/session_impl.hpp b/src/mtconnect/sink/rest_sink/session_impl.hpp index 404d25b9c..0d811a84a 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.hpp +++ b/src/mtconnect/sink/rest_sink/session_impl.hpp @@ -35,6 +35,12 @@ namespace mtconnect { } namespace sink::rest_sink { + template + class WebsocketSession; + template + using WebsocketSessionPtr = std::shared_ptr>; + + /// @brief A session implementation `Derived` subclass pattern /// @tparam subclass of this class to use the same methods with http or https protocol streams template @@ -61,7 +67,7 @@ namespace mtconnect { return std::dynamic_pointer_cast(shared_from_this()); } /// @brief get this as the `Derived` type - /// @return + /// @return the subclass Derived &derived() { return static_cast(*this); } /// @name Session Interface @@ -74,6 +80,8 @@ namespace mtconnect { void closeStream() override; ///@} protected: + using RequestMessage = boost::beast::http::request; + template void addHeaders(const Response &response, T &res); @@ -81,6 +89,7 @@ namespace mtconnect { void sent(boost::system::error_code ec, size_t len); void read(); void reset(); + void upgrade(RequestMessage &&msg); protected: using RequestParser = boost::beast::http::request_parser; @@ -144,6 +153,9 @@ namespace mtconnect { boost::beast::error_code ec; m_stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); } + + /// @brief Upgrade the current connection to a websocket connection. + SessionPtr upgradeToWebsocket(RequestMessage &&msg); protected: boost::beast::tcp_stream m_stream; diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp new file mode 100644 index 000000000..2d87ced24 --- /dev/null +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -0,0 +1,293 @@ +// +// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include +#include + +#include +#include + +#include +#include +#include + +#include "mtconnect/config.hpp" +#include "mtconnect/configuration/config_options.hpp" +#include "mtconnect/utilities.hpp" +#include "session.hpp" + +namespace mtconnect::sink::rest_sink { + namespace beast = boost::beast; + + /// @brief A websocket session that provides a pubsub interface using REST parameters + template + class WebsocketSession : public Session + { + public: + using RequestMessage = boost::beast::http::request; + + WebsocketSession(RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) + : Session(dispatch, func), m_request(std::move(request)), m_msg(std::move(msg)) + { + } + + /// @brief Session cannot be copied. + WebsocketSession(const WebsocketSession &) = delete; + ~WebsocketSession() = default; + + /// @brief get this as the `Derived` type + /// @return the subclass + Derived &derived() { return static_cast(*this); } + + + void run() override + { + using namespace boost::beast; + + // Set suggested timeout settings for the websocket + derived().stream().set_option( + websocket::stream_base::timeout::suggested( + beast::role_type::server)); + + // Set a decorator to change the Server of the handshake + derived().stream().set_option( + websocket::stream_base::decorator( + [](websocket::response_type& res) + { + res.set(http::field::server, + GetAgentVersion() + + " MTConnectAgent"); + })); + + // Accept the websocket handshake + derived().stream().async_accept( + m_msg, + beast::bind_front_handler( + &WebsocketSession::onAccept, + derived().shared_ptr())); + } + + void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override + { + + } + + void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override + { + } + + void beginStreaming(const std::string &mimeType, Complete complete) override + { + } + + void writeChunk(const std::string &chunk, Complete complete) override + { + + } + + void closeStream() override + { + } + + protected: + void onAccept(boost::beast::error_code ec) + { + if (ec) + { + fail(status::internal_server_error, "Error occurred in accpet", ec); + return; + } + + derived().stream().async_read( + m_buffer, + beast::bind_front_handler( + &WebsocketSession::onRead, + derived().shared_ptr())); + + } + + void onRead(beast::error_code ec, + std::size_t len) + { + using namespace rapidjson; + using namespace std; + + // Parse the buffer as a JSON request with parameters matching + // REST API + derived().stream().text(derived().stream().got_text()); + auto buffer = beast::buffers_to_string(m_buffer.data()); + + Document doc; + doc.Parse(buffer.c_str(), len); + + if (doc.HasParseError()) + { + LOG(warning) << "Websocket Read Error(offset (" << doc.GetErrorOffset() << "): " << + GetParseError_En(doc.GetParseError()); + LOG(warning) << " " << buffer; + } + if (!doc.IsObject()) + { + LOG(warning) << "Websocket Read Error: JSON message does not have a top level object"; + LOG(warning) << " " << buffer; + } + else + { + // Extract the parameters from the json doc to map them to the REST + // protocol parameters + auto request = std::make_shared(); + request->m_verb = beast::http::verb::get; + const auto &object = doc.GetObject(); + + for (auto &it : object) + { + switch (it.value.GetType()) + { + case rapidjson::kNullType: + // Skip nulls + break; + case rapidjson::kFalseType: + request->m_parameters.emplace(make_pair(it.name.GetString(), false)); + break; + case rapidjson::kTrueType: + request->m_parameters.emplace(make_pair(it.name.GetString(), true)); + break; + case rapidjson::kObjectType: + break; + case rapidjson::kArrayType: + break; + case rapidjson::kStringType: + request->m_parameters.emplace(make_pair(it.name.GetString(), string(it.value.GetString()))); + + break; + case rapidjson::kNumberType: + if (it.value.Is()) + request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + else if (it.value.Is()) + request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + else if (it.value.Is()) + request->m_parameters.emplace(make_pair(it.name.GetString(), (uint64_t) it.value.Get())); + else if (it.value.Is()) + request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + else if (it.value.Is()) + request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + + break; + } + } + + m_request->m_parsed = true; + if (!m_dispatch(derived().shared_ptr(), m_request)) + { + ostringstream txt; + txt << "Failed to find handler for " << buffer; + LOG(error) << txt.str(); + } + } + + derived().stream().async_read( + m_buffer, + beast::bind_front_handler( + &WebsocketSession::onRead, + derived().shared_ptr())); + } + + protected: + RequestPtr m_request; + RequestMessage m_msg; + beast::flat_buffer m_buffer; + }; + + template + using WebsocketSessionPtr = std::shared_ptr>; + + class PlainWebsocketSession : public WebsocketSession + { + public: + using Stream = beast::websocket::stream; + + PlainWebsocketSession(beast::tcp_stream&& stream, RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) + : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) + { + } + ~PlainWebsocketSession() + { + close(); + } + + void close() override + { + NAMED_SCOPE("PlainWebsocketSession::close"); + + m_request.reset(); + m_stream.close(beast::websocket::close_code::none); + } + + auto &stream() { return m_stream; } + + /// @brief Get a pointer cast as an Websocket Session + /// @return shared pointer to an Websocket session + std::shared_ptr shared_ptr() + { + return std::dynamic_pointer_cast(shared_from_this()); + } + + + + protected: + Stream m_stream; + }; + + class TlsWebsocketSession : public WebsocketSession + { + public: + using Stream = beast::websocket::stream>; + + TlsWebsocketSession(beast::ssl_stream&& stream, RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) + : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) + { + } + ~TlsWebsocketSession() + { + close(); + } + + auto &stream() { return m_stream; } + + void close() override + { + NAMED_SCOPE("TlsWebsocketSession::close"); + + m_request.reset(); + m_stream.close(beast::websocket::close_code::none); + } + + /// @brief Get a pointer cast as an TLS Websocket Session + /// @return shared pointer to an TLS Websocket session + std::shared_ptr shared_ptr() + { + return std::dynamic_pointer_cast(shared_from_this()); + } + + protected: + Stream m_stream; + }; + +} + From faa2f5323ea4d311b242a097695a3490cce4de5d Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 5 Apr 2024 21:41:43 -0400 Subject: [PATCH 064/128] updated copyright and added validations --- agent/cppagent.cpp | 2 +- agent_lib/CMakeLists.txt | 7 ++++ src/mtconnect/agent.cpp | 19 +++++++-- src/mtconnect/agent.hpp | 5 ++- src/mtconnect/asset/asset.cpp | 2 +- src/mtconnect/asset/asset.hpp | 2 +- src/mtconnect/asset/asset_buffer.hpp | 2 +- src/mtconnect/asset/asset_storage.hpp | 2 +- .../component_configuration_parameters.cpp | 2 +- .../component_configuration_parameters.hpp | 2 +- src/mtconnect/asset/cutting_tool.cpp | 2 +- src/mtconnect/asset/cutting_tool.hpp | 2 +- src/mtconnect/asset/file_asset.cpp | 2 +- src/mtconnect/asset/file_asset.hpp | 2 +- src/mtconnect/asset/qif_document.cpp | 2 +- src/mtconnect/asset/qif_document.hpp | 2 +- src/mtconnect/asset/raw_material.cpp | 2 +- src/mtconnect/asset/raw_material.hpp | 2 +- src/mtconnect/buffer/checkpoint.cpp | 2 +- src/mtconnect/buffer/checkpoint.hpp | 2 +- src/mtconnect/buffer/circular_buffer.hpp | 2 +- src/mtconnect/config.hpp | 2 +- src/mtconnect/configuration/agent_config.cpp | 5 ++- src/mtconnect/configuration/agent_config.hpp | 2 +- src/mtconnect/configuration/async_context.hpp | 2 +- .../configuration/config_options.hpp | 3 +- src/mtconnect/configuration/hook_manager.hpp | 2 +- src/mtconnect/configuration/parser.cpp | 2 +- src/mtconnect/configuration/parser.hpp | 2 +- src/mtconnect/configuration/service.cpp | 2 +- src/mtconnect/configuration/service.hpp | 2 +- src/mtconnect/device_model/agent_device.cpp | 2 +- src/mtconnect/device_model/agent_device.hpp | 2 +- src/mtconnect/device_model/component.cpp | 2 +- src/mtconnect/device_model/component.hpp | 2 +- src/mtconnect/device_model/composition.cpp | 2 +- src/mtconnect/device_model/composition.hpp | 2 +- .../configuration/configuration.cpp | 2 +- .../configuration/configuration.hpp | 2 +- .../configuration/coordinate_systems.cpp | 2 +- .../configuration/coordinate_systems.hpp | 2 +- .../device_model/configuration/image_file.cpp | 2 +- .../device_model/configuration/image_file.hpp | 2 +- .../device_model/configuration/motion.cpp | 2 +- .../device_model/configuration/motion.hpp | 2 +- .../configuration/relationships.cpp | 2 +- .../configuration/relationships.hpp | 2 +- .../configuration/sensor_configuration.cpp | 2 +- .../configuration/sensor_configuration.hpp | 2 +- .../configuration/solid_model.cpp | 2 +- .../configuration/solid_model.hpp | 2 +- .../configuration/specifications.cpp | 2 +- .../configuration/specifications.hpp | 2 +- .../device_model/data_item/constraints.hpp | 2 +- .../device_model/data_item/data_item.cpp | 2 +- .../device_model/data_item/data_item.hpp | 2 +- .../device_model/data_item/definition.hpp | 2 +- .../device_model/data_item/filter.hpp | 2 +- .../device_model/data_item/relationships.hpp | 2 +- .../device_model/data_item/source.hpp | 2 +- .../data_item/unit_conversion.cpp | 2 +- .../data_item/unit_conversion.hpp | 2 +- src/mtconnect/device_model/description.cpp | 2 +- src/mtconnect/device_model/description.hpp | 2 +- src/mtconnect/device_model/device.cpp | 2 +- src/mtconnect/device_model/device.hpp | 2 +- src/mtconnect/device_model/reference.cpp | 2 +- src/mtconnect/device_model/reference.hpp | 2 +- src/mtconnect/entity/data_set.cpp | 2 +- src/mtconnect/entity/data_set.hpp | 2 +- src/mtconnect/entity/entity.cpp | 2 +- src/mtconnect/entity/entity.hpp | 2 +- src/mtconnect/entity/factory.cpp | 2 +- src/mtconnect/entity/factory.hpp | 2 +- src/mtconnect/entity/json_parser.cpp | 2 +- src/mtconnect/entity/json_parser.hpp | 2 +- src/mtconnect/entity/json_printer.hpp | 2 +- src/mtconnect/entity/qname.hpp | 2 +- src/mtconnect/entity/requirement.cpp | 2 +- src/mtconnect/entity/requirement.hpp | 2 +- src/mtconnect/entity/xml_parser.cpp | 2 +- src/mtconnect/entity/xml_parser.hpp | 2 +- src/mtconnect/entity/xml_printer.cpp | 2 +- src/mtconnect/entity/xml_printer.hpp | 2 +- src/mtconnect/logging.hpp | 2 +- src/mtconnect/mqtt/mqtt_authorization.hpp | 2 +- src/mtconnect/mqtt/mqtt_client.hpp | 2 +- src/mtconnect/mqtt/mqtt_client_impl.hpp | 2 +- src/mtconnect/mqtt/mqtt_server.hpp | 2 +- src/mtconnect/mqtt/mqtt_server_impl.hpp | 2 +- src/mtconnect/observation/change_observer.cpp | 2 +- src/mtconnect/observation/change_observer.hpp | 2 +- src/mtconnect/observation/observation.cpp | 23 ++++++----- src/mtconnect/observation/observation.hpp | 2 +- src/mtconnect/parser/xml_parser.cpp | 2 +- src/mtconnect/parser/xml_parser.hpp | 2 +- src/mtconnect/pipeline/convert_sample.hpp | 2 +- src/mtconnect/pipeline/deliver.cpp | 2 +- src/mtconnect/pipeline/deliver.hpp | 2 +- src/mtconnect/pipeline/delta_filter.hpp | 2 +- src/mtconnect/pipeline/duplicate_filter.hpp | 2 +- src/mtconnect/pipeline/guard.hpp | 2 +- src/mtconnect/pipeline/json_mapper.cpp | 2 +- src/mtconnect/pipeline/json_mapper.hpp | 2 +- src/mtconnect/pipeline/message_mapper.hpp | 2 +- .../pipeline/mtconnect_xml_transform.hpp | 2 +- src/mtconnect/pipeline/period_filter.hpp | 2 +- src/mtconnect/pipeline/pipeline.hpp | 2 +- src/mtconnect/pipeline/pipeline_context.hpp | 2 +- src/mtconnect/pipeline/pipeline_contract.hpp | 2 +- src/mtconnect/pipeline/response_document.cpp | 2 +- src/mtconnect/pipeline/response_document.hpp | 2 +- src/mtconnect/pipeline/shdr_token_mapper.cpp | 2 +- src/mtconnect/pipeline/shdr_token_mapper.hpp | 2 +- src/mtconnect/pipeline/shdr_tokenizer.hpp | 2 +- .../pipeline/timestamp_extractor.hpp | 2 +- src/mtconnect/pipeline/topic_mapper.hpp | 2 +- src/mtconnect/pipeline/transform.hpp | 2 +- src/mtconnect/pipeline/upcase_value.hpp | 2 +- src/mtconnect/printer/json_printer.cpp | 32 +++++++++------ src/mtconnect/printer/json_printer.hpp | 4 +- src/mtconnect/printer/json_printer_helper.hpp | 2 +- src/mtconnect/printer/printer.hpp | 16 ++++++-- src/mtconnect/printer/xml_helper.hpp | 2 +- src/mtconnect/printer/xml_printer.cpp | 7 +++- src/mtconnect/printer/xml_printer.hpp | 4 +- src/mtconnect/printer/xml_printer_helper.hpp | 2 +- src/mtconnect/ruby/embedded.cpp | 2 +- src/mtconnect/ruby/embedded.hpp | 2 +- src/mtconnect/ruby/ruby_agent.hpp | 2 +- src/mtconnect/ruby/ruby_entity.hpp | 2 +- src/mtconnect/ruby/ruby_observation.hpp | 2 +- src/mtconnect/ruby/ruby_pipeline.hpp | 2 +- src/mtconnect/ruby/ruby_smart_ptr.hpp | 2 +- src/mtconnect/ruby/ruby_transform.hpp | 2 +- src/mtconnect/ruby/ruby_type.hpp | 2 +- src/mtconnect/ruby/ruby_vm.hpp | 2 +- src/mtconnect/sink/mqtt_sink/mqtt_service.cpp | 2 +- src/mtconnect/sink/mqtt_sink/mqtt_service.hpp | 2 +- src/mtconnect/sink/rest_sink/cached_file.hpp | 2 +- src/mtconnect/sink/rest_sink/file_cache.cpp | 2 +- src/mtconnect/sink/rest_sink/file_cache.hpp | 2 +- src/mtconnect/sink/rest_sink/parameter.hpp | 2 +- src/mtconnect/sink/rest_sink/request.hpp | 2 +- src/mtconnect/sink/rest_sink/response.hpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.hpp | 2 +- src/mtconnect/sink/rest_sink/routing.hpp | 2 +- src/mtconnect/sink/rest_sink/server.cpp | 2 +- src/mtconnect/sink/rest_sink/server.hpp | 2 +- src/mtconnect/sink/rest_sink/session.hpp | 2 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 2 +- src/mtconnect/sink/rest_sink/session_impl.hpp | 2 +- src/mtconnect/sink/rest_sink/tls_dector.hpp | 2 +- src/mtconnect/sink/sink.cpp | 2 +- src/mtconnect/sink/sink.hpp | 2 +- src/mtconnect/source/adapter/adapter.hpp | 2 +- .../source/adapter/adapter_pipeline.cpp | 2 +- .../source/adapter/adapter_pipeline.hpp | 2 +- .../adapter/agent_adapter/agent_adapter.cpp | 2 +- .../adapter/agent_adapter/agent_adapter.hpp | 2 +- .../adapter/agent_adapter/http_session.hpp | 2 +- .../adapter/agent_adapter/https_session.hpp | 2 +- .../source/adapter/agent_adapter/session.hpp | 2 +- .../adapter/agent_adapter/session_impl.hpp | 2 +- .../source/adapter/mqtt/mqtt_adapter.cpp | 2 +- .../source/adapter/mqtt/mqtt_adapter.hpp | 2 +- .../source/adapter/shdr/connector.cpp | 2 +- .../source/adapter/shdr/connector.hpp | 2 +- .../source/adapter/shdr/shdr_adapter.cpp | 2 +- .../source/adapter/shdr/shdr_adapter.hpp | 2 +- .../source/adapter/shdr/shdr_pipeline.cpp | 2 +- .../source/adapter/shdr/shdr_pipeline.hpp | 2 +- src/mtconnect/source/error_code.hpp | 2 +- src/mtconnect/source/loopback_source.cpp | 2 +- src/mtconnect/source/loopback_source.hpp | 2 +- src/mtconnect/source/source.cpp | 2 +- src/mtconnect/source/source.hpp | 2 +- src/mtconnect/utilities.cpp | 2 +- src/mtconnect/utilities.hpp | 2 +- .../validation/observation_validations.hpp | 39 +++++++++++++++++++ src/mtconnect/validation/observations.cpp | 22 +++++++++++ src/mtconnect/validation/observations.hpp | 29 ++++++++++++++ src/mtconnect/version.cpp | 2 +- test_package/adapter_test.cpp | 2 +- test_package/agent_adapter_test.cpp | 2 +- test_package/agent_device_test.cpp | 2 +- test_package/agent_test.cpp | 2 +- test_package/agent_test_helper.cpp | 2 +- test_package/agent_test_helper.hpp | 2 +- test_package/asset_buffer_test.cpp | 2 +- test_package/asset_hash_test.cpp | 2 +- test_package/asset_test.cpp | 2 +- test_package/change_observer_test.cpp | 2 +- test_package/checkpoint_test.cpp | 2 +- test_package/circular_buffer_test.cpp | 2 +- test_package/component_parameters_test.cpp | 2 +- test_package/component_test.cpp | 2 +- test_package/composition_test.cpp | 2 +- test_package/config_parser_test.cpp | 2 +- test_package/config_test.cpp | 2 +- test_package/connector_test.cpp | 2 +- test_package/coordinate_system_test.cpp | 2 +- test_package/cutting_tool_test.cpp | 2 +- test_package/data_item_mapping_test.cpp | 2 +- test_package/data_item_test.cpp | 2 +- test_package/data_set_test.cpp | 2 +- test_package/device_test.cpp | 2 +- test_package/duplicate_filter_test.cpp | 2 +- test_package/embedded_ruby_test.cpp | 2 +- test_package/entity_parser_test.cpp | 2 +- test_package/entity_printer_test.cpp | 2 +- test_package/entity_test.cpp | 2 +- test_package/file_asset_test.cpp | 2 +- test_package/file_cache_test.cpp | 2 +- test_package/globals_test.cpp | 2 +- test_package/http_server_test.cpp | 2 +- test_package/image_file_test.cpp | 2 +- test_package/json_helper.hpp | 2 +- test_package/json_mapping_test.cpp | 2 +- test_package/json_parser_test.cpp | 2 +- test_package/json_printer_asset_test.cpp | 2 +- test_package/json_printer_error_test.cpp | 2 +- test_package/json_printer_probe_test.cpp | 2 +- test_package/json_printer_stream_test.cpp | 2 +- test_package/json_printer_test.cpp | 2 +- test_package/kinematics_test.cpp | 2 +- test_package/mqtt_adapter_test.cpp | 2 +- test_package/mqtt_isolated_test.cpp | 2 +- test_package/mqtt_sink_2_test.cpp | 2 +- test_package/mqtt_sink_test.cpp | 2 +- test_package/mtconnect_xml_transform_test.cpp | 2 +- test_package/observation_test.cpp | 2 +- test_package/period_filter_test.cpp | 2 +- test_package/pipeline_deliver_test.cpp | 2 +- test_package/pipeline_edit_test.cpp | 2 +- test_package/qif_document_test.cpp | 2 +- test_package/qname_test.cpp | 2 +- test_package/raw_material_test.cpp | 2 +- test_package/references_test.cpp | 2 +- test_package/relationship_test.cpp | 2 +- test_package/response_document_test.cpp | 2 +- test_package/routing_test.cpp | 2 +- test_package/sensor_configuration_test.cpp | 2 +- test_package/shdr_tokenizer_test.cpp | 2 +- test_package/solid_model_test.cpp | 2 +- test_package/specification_test.cpp | 2 +- test_package/table_test.cpp | 2 +- test_package/test_utilities.hpp | 2 +- test_package/testadapter_service.cpp | 2 +- test_package/testadapter_service.hpp | 2 +- test_package/testsink_service.cpp | 2 +- test_package/testsink_service.hpp | 2 +- test_package/timestamp_extractor_test.cpp | 2 +- test_package/tls_http_server_test.cpp | 2 +- test_package/topic_mapping_test.cpp | 2 +- test_package/unit_conversion_test.cpp | 2 +- test_package/url_parser_test.cpp | 2 +- test_package/xml_parser_test.cpp | 2 +- test_package/xml_printer_test.cpp | 2 +- 260 files changed, 422 insertions(+), 285 deletions(-) create mode 100644 src/mtconnect/validation/observation_validations.hpp create mode 100644 src/mtconnect/validation/observations.cpp create mode 100644 src/mtconnect/validation/observations.hpp diff --git a/agent/cppagent.cpp b/agent/cppagent.cpp index ae86382a3..3557e01a4 100644 --- a/agent/cppagent.cpp +++ b/agent/cppagent.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index 93d2d9a6e..028b3a101 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -272,6 +272,13 @@ set(AGENT_SOURCES "${SOURCE_DIR}/sink/rest_sink/rest_service.cpp" "${SOURCE_DIR}/sink/rest_sink/server.cpp" "${SOURCE_DIR}/sink/rest_sink/session_impl.cpp" + + # validation HEADER_FILES_ONLY + "${SOURCE_DIR}/validation/observations.hpp" + "${SOURCE_DIR}/validation/observation_validations.hpp" + + # validation SOURCE_FILES_ONLY + "${SOURCE_DIR}/validation/observations.cpp" ) if(WITH_RUBY) diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index d350f92ca..272c23471 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -60,6 +60,8 @@ #include "mtconnect/utilities.hpp" #include "mtconnect/version.h" +#include "mtconnect/validation/observations.hpp" + using namespace std; namespace mtconnect { @@ -85,7 +87,8 @@ namespace mtconnect { m_deviceXmlPath(deviceXmlPath), m_circularBuffer(GetOption(options, config::BufferSize).value_or(17), GetOption(options, config::CheckpointFrequency).value_or(1000)), - m_pretty(IsOptionSet(options, mtconnect::configuration::Pretty)) + m_pretty(IsOptionSet(options, mtconnect::configuration::Pretty)), + m_validation(IsOptionSet(options, mtconnect::configuration::Validation)) { using namespace asset; @@ -106,8 +109,8 @@ namespace mtconnect { uint32_t(GetOption(options, mtconnect::configuration::JsonVersion).value_or(2)); // Create the Printers - m_printers["xml"] = make_unique(m_pretty); - m_printers["json"] = make_unique(jsonVersion, m_pretty); + m_printers["xml"] = make_unique(m_pretty, m_validation); + m_printers["json"] = make_unique(jsonVersion, m_pretty, m_validation); if (m_schemaVersion) { @@ -170,6 +173,13 @@ namespace mtconnect { if (!m_observationsInitialized) { + if (m_intSchemaVersion < SCHEMA_VERSION(2, 5) && IsOptionSet(m_options, mtconnect::configuration::Validation)) + { + m_validation = false; + for (auto &printer : m_printers) + printer.second->setValidation(false); + } + for (auto device : m_deviceIndex) initializeDataItems(device); @@ -193,6 +203,7 @@ namespace mtconnect { } m_observationsInitialized = true; + } } diff --git a/src/mtconnect/agent.hpp b/src/mtconnect/agent.hpp index c827d7cf3..6fd347651 100644 --- a/src/mtconnect/agent.hpp +++ b/src/mtconnect/agent.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -542,6 +542,9 @@ namespace mtconnect { // For debugging bool m_pretty; + // validation + bool m_validation {false}; + // Agent hooks configuration::HookManager m_beforeInitializeHooks; configuration::HookManager m_afterInitializeHooks; diff --git a/src/mtconnect/asset/asset.cpp b/src/mtconnect/asset/asset.cpp index ecda782de..ac51d0cd9 100644 --- a/src/mtconnect/asset/asset.cpp +++ b/src/mtconnect/asset/asset.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/asset.hpp b/src/mtconnect/asset/asset.hpp index aea57917d..6d9fdc096 100644 --- a/src/mtconnect/asset/asset.hpp +++ b/src/mtconnect/asset/asset.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/asset_buffer.hpp b/src/mtconnect/asset/asset_buffer.hpp index b4aa75bff..662780745 100644 --- a/src/mtconnect/asset/asset_buffer.hpp +++ b/src/mtconnect/asset/asset_buffer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/asset_storage.hpp b/src/mtconnect/asset/asset_storage.hpp index dcccae645..ff90e49a4 100644 --- a/src/mtconnect/asset/asset_storage.hpp +++ b/src/mtconnect/asset/asset_storage.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/component_configuration_parameters.cpp b/src/mtconnect/asset/component_configuration_parameters.cpp index 100652671..d341b6d8c 100644 --- a/src/mtconnect/asset/component_configuration_parameters.cpp +++ b/src/mtconnect/asset/component_configuration_parameters.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/component_configuration_parameters.hpp b/src/mtconnect/asset/component_configuration_parameters.hpp index ef45675fb..fc40d3449 100644 --- a/src/mtconnect/asset/component_configuration_parameters.hpp +++ b/src/mtconnect/asset/component_configuration_parameters.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/cutting_tool.cpp b/src/mtconnect/asset/cutting_tool.cpp index 579350bcb..43d5303af 100644 --- a/src/mtconnect/asset/cutting_tool.cpp +++ b/src/mtconnect/asset/cutting_tool.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/cutting_tool.hpp b/src/mtconnect/asset/cutting_tool.hpp index 1c3e820c9..7eec093e6 100644 --- a/src/mtconnect/asset/cutting_tool.hpp +++ b/src/mtconnect/asset/cutting_tool.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/file_asset.cpp b/src/mtconnect/asset/file_asset.cpp index 222b97f97..b001c86ca 100644 --- a/src/mtconnect/asset/file_asset.cpp +++ b/src/mtconnect/asset/file_asset.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/file_asset.hpp b/src/mtconnect/asset/file_asset.hpp index 380f26bcb..9c5ea9797 100644 --- a/src/mtconnect/asset/file_asset.hpp +++ b/src/mtconnect/asset/file_asset.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/qif_document.cpp b/src/mtconnect/asset/qif_document.cpp index bf7b77913..6c762cd12 100644 --- a/src/mtconnect/asset/qif_document.cpp +++ b/src/mtconnect/asset/qif_document.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/qif_document.hpp b/src/mtconnect/asset/qif_document.hpp index e1c58fcfd..45bc7f2f2 100644 --- a/src/mtconnect/asset/qif_document.hpp +++ b/src/mtconnect/asset/qif_document.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/raw_material.cpp b/src/mtconnect/asset/raw_material.cpp index a9a44d3f3..0ca15b37d 100644 --- a/src/mtconnect/asset/raw_material.cpp +++ b/src/mtconnect/asset/raw_material.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/asset/raw_material.hpp b/src/mtconnect/asset/raw_material.hpp index 2612ed5d8..76af8d858 100644 --- a/src/mtconnect/asset/raw_material.hpp +++ b/src/mtconnect/asset/raw_material.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/buffer/checkpoint.cpp b/src/mtconnect/buffer/checkpoint.cpp index a0e32f6e8..fd5ec3034 100644 --- a/src/mtconnect/buffer/checkpoint.cpp +++ b/src/mtconnect/buffer/checkpoint.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/buffer/checkpoint.hpp b/src/mtconnect/buffer/checkpoint.hpp index 7e7c582a8..b830c223d 100644 --- a/src/mtconnect/buffer/checkpoint.hpp +++ b/src/mtconnect/buffer/checkpoint.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/buffer/circular_buffer.hpp b/src/mtconnect/buffer/circular_buffer.hpp index e9b934ae3..eb3b3f4d6 100644 --- a/src/mtconnect/buffer/circular_buffer.hpp +++ b/src/mtconnect/buffer/circular_buffer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/config.hpp b/src/mtconnect/config.hpp index 219d245d6..a522fe123 100644 --- a/src/mtconnect/config.hpp +++ b/src/mtconnect/config.hpp @@ -1,7 +1,7 @@ #pragma once // -// Copyright Copyright 2009-2022, AMT � The Association For Manufacturing Technology (�AMT�) +// Copyright Copyright 2009-2024, AMT � The Association For Manufacturing Technology (�AMT�) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index c87e5b854..59dc8a360 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -789,7 +789,8 @@ namespace mtconnect::configuration { {configuration::TlsVerifyClientCertificate, false}, {configuration::TlsClientCAs, ""s}, {configuration::SuppressIPAddress, false}, - {configuration::AllowPutFrom, ""s}}); + {configuration::AllowPutFrom, ""s}, + {configuration::Validation, false}}); m_workerThreadCount = *GetOption(options, configuration::WorkerThreads); m_monitorFiles = *GetOption(options, configuration::MonitorConfigFiles); diff --git a/src/mtconnect/configuration/agent_config.hpp b/src/mtconnect/configuration/agent_config.hpp index 61b39bbd1..dd68f198f 100644 --- a/src/mtconnect/configuration/agent_config.hpp +++ b/src/mtconnect/configuration/agent_config.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/async_context.hpp b/src/mtconnect/configuration/async_context.hpp index 81a31254d..910c07ee1 100644 --- a/src/mtconnect/configuration/async_context.hpp +++ b/src/mtconnect/configuration/async_context.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/config_options.hpp b/src/mtconnect/configuration/config_options.hpp index 11ac1dd91..9c2857c48 100644 --- a/src/mtconnect/configuration/config_options.hpp +++ b/src/mtconnect/configuration/config_options.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -76,6 +76,7 @@ namespace mtconnect { DECLARE_CONFIGURATION(VersionDeviceXml); DECLARE_CONFIGURATION(EnableSourceDeviceModels); DECLARE_CONFIGURATION(WorkerThreads); + DECLARE_CONFIGURATION(Validation); ///@} /// @name MQTT Configuration diff --git a/src/mtconnect/configuration/hook_manager.hpp b/src/mtconnect/configuration/hook_manager.hpp index 4c62cc041..d831146c8 100644 --- a/src/mtconnect/configuration/hook_manager.hpp +++ b/src/mtconnect/configuration/hook_manager.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/parser.cpp b/src/mtconnect/configuration/parser.cpp index e145441d8..2baeb8e15 100644 --- a/src/mtconnect/configuration/parser.cpp +++ b/src/mtconnect/configuration/parser.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/parser.hpp b/src/mtconnect/configuration/parser.hpp index 63fe41c3f..13d9bb0d8 100644 --- a/src/mtconnect/configuration/parser.hpp +++ b/src/mtconnect/configuration/parser.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/service.cpp b/src/mtconnect/configuration/service.cpp index 07dfe8db9..a3ef8c0dd 100644 --- a/src/mtconnect/configuration/service.cpp +++ b/src/mtconnect/configuration/service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/configuration/service.hpp b/src/mtconnect/configuration/service.hpp index b61b67a81..fca63e1e5 100644 --- a/src/mtconnect/configuration/service.hpp +++ b/src/mtconnect/configuration/service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/agent_device.cpp b/src/mtconnect/device_model/agent_device.cpp index ef6df6022..dc2e6c6a9 100644 --- a/src/mtconnect/device_model/agent_device.cpp +++ b/src/mtconnect/device_model/agent_device.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/agent_device.hpp b/src/mtconnect/device_model/agent_device.hpp index 6bbe34558..4b693b5e6 100644 --- a/src/mtconnect/device_model/agent_device.hpp +++ b/src/mtconnect/device_model/agent_device.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/component.cpp b/src/mtconnect/device_model/component.cpp index 4935eddaa..779bccc12 100644 --- a/src/mtconnect/device_model/component.cpp +++ b/src/mtconnect/device_model/component.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/component.hpp b/src/mtconnect/device_model/component.hpp index ca0c09d42..911b7a5ad 100644 --- a/src/mtconnect/device_model/component.hpp +++ b/src/mtconnect/device_model/component.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/composition.cpp b/src/mtconnect/device_model/composition.cpp index 923938b34..40f57cd2a 100644 --- a/src/mtconnect/device_model/composition.cpp +++ b/src/mtconnect/device_model/composition.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/composition.hpp b/src/mtconnect/device_model/composition.hpp index 3ad2046cb..97bdad4c5 100644 --- a/src/mtconnect/device_model/composition.hpp +++ b/src/mtconnect/device_model/composition.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/configuration.cpp b/src/mtconnect/device_model/configuration/configuration.cpp index 4f0a5119f..44cbcaa71 100644 --- a/src/mtconnect/device_model/configuration/configuration.cpp +++ b/src/mtconnect/device_model/configuration/configuration.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/configuration.hpp b/src/mtconnect/device_model/configuration/configuration.hpp index f9f707396..dc01d1f3f 100644 --- a/src/mtconnect/device_model/configuration/configuration.hpp +++ b/src/mtconnect/device_model/configuration/configuration.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/coordinate_systems.cpp b/src/mtconnect/device_model/configuration/coordinate_systems.cpp index d5b96a92c..adc9be6fc 100644 --- a/src/mtconnect/device_model/configuration/coordinate_systems.cpp +++ b/src/mtconnect/device_model/configuration/coordinate_systems.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/coordinate_systems.hpp b/src/mtconnect/device_model/configuration/coordinate_systems.hpp index ea414c33d..8fdc819f3 100644 --- a/src/mtconnect/device_model/configuration/coordinate_systems.hpp +++ b/src/mtconnect/device_model/configuration/coordinate_systems.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/image_file.cpp b/src/mtconnect/device_model/configuration/image_file.cpp index 29d6b9a45..84be05aaa 100644 --- a/src/mtconnect/device_model/configuration/image_file.cpp +++ b/src/mtconnect/device_model/configuration/image_file.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/image_file.hpp b/src/mtconnect/device_model/configuration/image_file.hpp index 32448fbea..6aac7f61c 100644 --- a/src/mtconnect/device_model/configuration/image_file.hpp +++ b/src/mtconnect/device_model/configuration/image_file.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/motion.cpp b/src/mtconnect/device_model/configuration/motion.cpp index a5ecd8188..5a863a440 100644 --- a/src/mtconnect/device_model/configuration/motion.cpp +++ b/src/mtconnect/device_model/configuration/motion.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/motion.hpp b/src/mtconnect/device_model/configuration/motion.hpp index ec73c9c27..1594e309d 100644 --- a/src/mtconnect/device_model/configuration/motion.hpp +++ b/src/mtconnect/device_model/configuration/motion.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/relationships.cpp b/src/mtconnect/device_model/configuration/relationships.cpp index bcfba65c1..a2ed6d78f 100644 --- a/src/mtconnect/device_model/configuration/relationships.cpp +++ b/src/mtconnect/device_model/configuration/relationships.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/relationships.hpp b/src/mtconnect/device_model/configuration/relationships.hpp index 62eeb75ac..c2a6fb462 100644 --- a/src/mtconnect/device_model/configuration/relationships.hpp +++ b/src/mtconnect/device_model/configuration/relationships.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/sensor_configuration.cpp b/src/mtconnect/device_model/configuration/sensor_configuration.cpp index b82abae6c..2bb26ecde 100644 --- a/src/mtconnect/device_model/configuration/sensor_configuration.cpp +++ b/src/mtconnect/device_model/configuration/sensor_configuration.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/sensor_configuration.hpp b/src/mtconnect/device_model/configuration/sensor_configuration.hpp index 8a4c54b5c..8eeb25b64 100644 --- a/src/mtconnect/device_model/configuration/sensor_configuration.hpp +++ b/src/mtconnect/device_model/configuration/sensor_configuration.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/solid_model.cpp b/src/mtconnect/device_model/configuration/solid_model.cpp index e2341a7fa..6c96236b1 100644 --- a/src/mtconnect/device_model/configuration/solid_model.cpp +++ b/src/mtconnect/device_model/configuration/solid_model.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/solid_model.hpp b/src/mtconnect/device_model/configuration/solid_model.hpp index 71d60bcfd..fa406d9a5 100644 --- a/src/mtconnect/device_model/configuration/solid_model.hpp +++ b/src/mtconnect/device_model/configuration/solid_model.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/specifications.cpp b/src/mtconnect/device_model/configuration/specifications.cpp index fe74c894c..a4d55bc0c 100644 --- a/src/mtconnect/device_model/configuration/specifications.cpp +++ b/src/mtconnect/device_model/configuration/specifications.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/configuration/specifications.hpp b/src/mtconnect/device_model/configuration/specifications.hpp index 90da6bc3a..226af76a1 100644 --- a/src/mtconnect/device_model/configuration/specifications.hpp +++ b/src/mtconnect/device_model/configuration/specifications.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/constraints.hpp b/src/mtconnect/device_model/data_item/constraints.hpp index e6b919888..21c362955 100644 --- a/src/mtconnect/device_model/data_item/constraints.hpp +++ b/src/mtconnect/device_model/data_item/constraints.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/data_item.cpp b/src/mtconnect/device_model/data_item/data_item.cpp index 0a21d976c..b0596fbd1 100644 --- a/src/mtconnect/device_model/data_item/data_item.cpp +++ b/src/mtconnect/device_model/data_item/data_item.cpp @@ -1,6 +1,6 @@ // // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/data_item.hpp b/src/mtconnect/device_model/data_item/data_item.hpp index 3efcad2f9..8a7c6959c 100644 --- a/src/mtconnect/device_model/data_item/data_item.hpp +++ b/src/mtconnect/device_model/data_item/data_item.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/definition.hpp b/src/mtconnect/device_model/data_item/definition.hpp index 69a5d0b5c..f1ba7245b 100644 --- a/src/mtconnect/device_model/data_item/definition.hpp +++ b/src/mtconnect/device_model/data_item/definition.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/filter.hpp b/src/mtconnect/device_model/data_item/filter.hpp index 0d32733fe..779f6d3cc 100644 --- a/src/mtconnect/device_model/data_item/filter.hpp +++ b/src/mtconnect/device_model/data_item/filter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/relationships.hpp b/src/mtconnect/device_model/data_item/relationships.hpp index 47bc187da..10c34c8c3 100644 --- a/src/mtconnect/device_model/data_item/relationships.hpp +++ b/src/mtconnect/device_model/data_item/relationships.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/source.hpp b/src/mtconnect/device_model/data_item/source.hpp index 561aaa383..e0895282d 100644 --- a/src/mtconnect/device_model/data_item/source.hpp +++ b/src/mtconnect/device_model/data_item/source.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/unit_conversion.cpp b/src/mtconnect/device_model/data_item/unit_conversion.cpp index cfa83b612..6a51aae72 100644 --- a/src/mtconnect/device_model/data_item/unit_conversion.cpp +++ b/src/mtconnect/device_model/data_item/unit_conversion.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/data_item/unit_conversion.hpp b/src/mtconnect/device_model/data_item/unit_conversion.hpp index c20fd5151..068a43aa7 100644 --- a/src/mtconnect/device_model/data_item/unit_conversion.hpp +++ b/src/mtconnect/device_model/data_item/unit_conversion.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/description.cpp b/src/mtconnect/device_model/description.cpp index fe999e94b..9a7c1cb4f 100644 --- a/src/mtconnect/device_model/description.cpp +++ b/src/mtconnect/device_model/description.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/description.hpp b/src/mtconnect/device_model/description.hpp index c6c5059df..8789eba6f 100644 --- a/src/mtconnect/device_model/description.hpp +++ b/src/mtconnect/device_model/description.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/device.cpp b/src/mtconnect/device_model/device.cpp index bdfed3bdd..e427c02b1 100644 --- a/src/mtconnect/device_model/device.cpp +++ b/src/mtconnect/device_model/device.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/device.hpp b/src/mtconnect/device_model/device.hpp index b811fd79c..d4ae2a80c 100644 --- a/src/mtconnect/device_model/device.hpp +++ b/src/mtconnect/device_model/device.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/reference.cpp b/src/mtconnect/device_model/reference.cpp index c58bb23d0..bc48b32fa 100644 --- a/src/mtconnect/device_model/reference.cpp +++ b/src/mtconnect/device_model/reference.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/device_model/reference.hpp b/src/mtconnect/device_model/reference.hpp index bb91d55ef..ba9595a5a 100644 --- a/src/mtconnect/device_model/reference.hpp +++ b/src/mtconnect/device_model/reference.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT � The Association For Manufacturing Technology (�AMT�) +// Copyright Copyright 2009-2024, AMT � The Association For Manufacturing Technology (�AMT�) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/data_set.cpp b/src/mtconnect/entity/data_set.cpp index 598d5b811..016f5c302 100644 --- a/src/mtconnect/entity/data_set.cpp +++ b/src/mtconnect/entity/data_set.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/data_set.hpp b/src/mtconnect/entity/data_set.hpp index 1602efb42..0fdaa5983 100644 --- a/src/mtconnect/entity/data_set.hpp +++ b/src/mtconnect/entity/data_set.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/entity.cpp b/src/mtconnect/entity/entity.cpp index 777eb306c..99e0b409c 100644 --- a/src/mtconnect/entity/entity.cpp +++ b/src/mtconnect/entity/entity.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/entity.hpp b/src/mtconnect/entity/entity.hpp index b56eec383..8f45cd319 100644 --- a/src/mtconnect/entity/entity.hpp +++ b/src/mtconnect/entity/entity.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/factory.cpp b/src/mtconnect/entity/factory.cpp index 0d1b24ea6..e763accdd 100644 --- a/src/mtconnect/entity/factory.cpp +++ b/src/mtconnect/entity/factory.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/factory.hpp b/src/mtconnect/entity/factory.hpp index 5b19c0c93..b5e1d411c 100644 --- a/src/mtconnect/entity/factory.hpp +++ b/src/mtconnect/entity/factory.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/json_parser.cpp b/src/mtconnect/entity/json_parser.cpp index 03db5f97c..3976d2fb6 100644 --- a/src/mtconnect/entity/json_parser.cpp +++ b/src/mtconnect/entity/json_parser.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT The Association For Manufacturing Technology (AMT) +// Copyright Copyright 2009-2024, AMT The Association For Manufacturing Technology (AMT) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/json_parser.hpp b/src/mtconnect/entity/json_parser.hpp index 90f2bb015..2fa29a0bb 100644 --- a/src/mtconnect/entity/json_parser.hpp +++ b/src/mtconnect/entity/json_parser.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT � The Association For Manufacturing Technology (�AMT�) +// Copyright Copyright 2009-2024, AMT � The Association For Manufacturing Technology (�AMT�) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/json_printer.hpp b/src/mtconnect/entity/json_printer.hpp index 24e9629ad..424b7617c 100644 --- a/src/mtconnect/entity/json_printer.hpp +++ b/src/mtconnect/entity/json_printer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/qname.hpp b/src/mtconnect/entity/qname.hpp index 449708404..c2c5b9eda 100644 --- a/src/mtconnect/entity/qname.hpp +++ b/src/mtconnect/entity/qname.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/requirement.cpp b/src/mtconnect/entity/requirement.cpp index e93c7bccc..854fd7e17 100644 --- a/src/mtconnect/entity/requirement.cpp +++ b/src/mtconnect/entity/requirement.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/requirement.hpp b/src/mtconnect/entity/requirement.hpp index 92c57f343..a4a9832bb 100644 --- a/src/mtconnect/entity/requirement.hpp +++ b/src/mtconnect/entity/requirement.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/xml_parser.cpp b/src/mtconnect/entity/xml_parser.cpp index 8fb2c63f1..9c7a37f78 100644 --- a/src/mtconnect/entity/xml_parser.cpp +++ b/src/mtconnect/entity/xml_parser.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/xml_parser.hpp b/src/mtconnect/entity/xml_parser.hpp index 8e66a5f33..d771dc866 100644 --- a/src/mtconnect/entity/xml_parser.hpp +++ b/src/mtconnect/entity/xml_parser.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/xml_printer.cpp b/src/mtconnect/entity/xml_printer.cpp index 97dd96ab3..799cf2561 100644 --- a/src/mtconnect/entity/xml_printer.cpp +++ b/src/mtconnect/entity/xml_printer.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/entity/xml_printer.hpp b/src/mtconnect/entity/xml_printer.hpp index 9d556bbf7..23a8aa5dd 100644 --- a/src/mtconnect/entity/xml_printer.hpp +++ b/src/mtconnect/entity/xml_printer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/logging.hpp b/src/mtconnect/logging.hpp index 0d21a757e..5e2d613f2 100644 --- a/src/mtconnect/logging.hpp +++ b/src/mtconnect/logging.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/mqtt/mqtt_authorization.hpp b/src/mtconnect/mqtt/mqtt_authorization.hpp index 08105aa27..73c79ace2 100644 --- a/src/mtconnect/mqtt/mqtt_authorization.hpp +++ b/src/mtconnect/mqtt/mqtt_authorization.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/mqtt/mqtt_client.hpp b/src/mtconnect/mqtt/mqtt_client.hpp index fe9d1ad83..0924f926b 100644 --- a/src/mtconnect/mqtt/mqtt_client.hpp +++ b/src/mtconnect/mqtt/mqtt_client.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index 0084e0e26..3997a4477 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/mqtt/mqtt_server.hpp b/src/mtconnect/mqtt/mqtt_server.hpp index 55a0ccf2e..8d38700a9 100644 --- a/src/mtconnect/mqtt/mqtt_server.hpp +++ b/src/mtconnect/mqtt/mqtt_server.hpp @@ -1,5 +1,5 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/src/mtconnect/mqtt/mqtt_server_impl.hpp b/src/mtconnect/mqtt/mqtt_server_impl.hpp index 13bd773b8..4c3b05715 100644 --- a/src/mtconnect/mqtt/mqtt_server_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_server_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index bdf4143e4..88b5c5da4 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index f08ca61ae..3f4e5c2eb 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/observation/observation.cpp b/src/mtconnect/observation/observation.cpp index 2a6c33dd5..fc8c56282 100644 --- a/src/mtconnect/observation/observation.cpp +++ b/src/mtconnect/observation/observation.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -41,15 +41,18 @@ namespace mtconnect { static FactoryPtr factory; if (!factory) { - factory = make_shared(Requirements({{"dataItemId", true}, - {"timestamp", ValueType::TIMESTAMP, true}, - {"sequence", false}, - {"subType", false}, - {"name", false}, - {"compositionId", false}}), - [](const std::string &name, Properties &props) -> EntityPtr { - return make_shared(name, props); - }); + factory = make_shared( + Requirements({{"dataItemId", true}, + {"timestamp", ValueType::TIMESTAMP, true}, + {"sequence", false}, + {"subType", false}, + {"name", false}, + {"compositionId", false}, + {"quality", ControlledVocab {"VALID", "INVALID", "UNVERIFIABLE"}, false}, + {"deprecated", ValueType::BOOL, false}}), + [](const std::string &name, Properties &props) -> EntityPtr { + return make_shared(name, props); + }); factory->registerFactory("Events:Message", Message::getFactory()); factory->registerFactory("Events:MessageDiscrete", Message::getFactory()); diff --git a/src/mtconnect/observation/observation.hpp b/src/mtconnect/observation/observation.hpp index ffc0f3d0f..bc2e48537 100644 --- a/src/mtconnect/observation/observation.hpp +++ b/src/mtconnect/observation/observation.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/parser/xml_parser.cpp b/src/mtconnect/parser/xml_parser.cpp index 14b4199ca..6485ecfef 100644 --- a/src/mtconnect/parser/xml_parser.cpp +++ b/src/mtconnect/parser/xml_parser.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/parser/xml_parser.hpp b/src/mtconnect/parser/xml_parser.hpp index eff7ac9cb..e5747c987 100644 --- a/src/mtconnect/parser/xml_parser.hpp +++ b/src/mtconnect/parser/xml_parser.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/convert_sample.hpp b/src/mtconnect/pipeline/convert_sample.hpp index 854109bbb..90dc9e907 100644 --- a/src/mtconnect/pipeline/convert_sample.hpp +++ b/src/mtconnect/pipeline/convert_sample.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/deliver.cpp b/src/mtconnect/pipeline/deliver.cpp index bf7788767..a97af1b20 100644 --- a/src/mtconnect/pipeline/deliver.cpp +++ b/src/mtconnect/pipeline/deliver.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/deliver.hpp b/src/mtconnect/pipeline/deliver.hpp index 47e615b2a..f48b45080 100644 --- a/src/mtconnect/pipeline/deliver.hpp +++ b/src/mtconnect/pipeline/deliver.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/delta_filter.hpp b/src/mtconnect/pipeline/delta_filter.hpp index d84a8084b..313f92e49 100644 --- a/src/mtconnect/pipeline/delta_filter.hpp +++ b/src/mtconnect/pipeline/delta_filter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/duplicate_filter.hpp b/src/mtconnect/pipeline/duplicate_filter.hpp index 21f5e49d1..c9fbf09d0 100644 --- a/src/mtconnect/pipeline/duplicate_filter.hpp +++ b/src/mtconnect/pipeline/duplicate_filter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/guard.hpp b/src/mtconnect/pipeline/guard.hpp index 43bf83a23..98cb89dca 100644 --- a/src/mtconnect/pipeline/guard.hpp +++ b/src/mtconnect/pipeline/guard.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/json_mapper.cpp b/src/mtconnect/pipeline/json_mapper.cpp index 8d94a83c0..9be7b4e52 100644 --- a/src/mtconnect/pipeline/json_mapper.cpp +++ b/src/mtconnect/pipeline/json_mapper.cpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/json_mapper.hpp b/src/mtconnect/pipeline/json_mapper.hpp index e2c75dcbb..d437a6b5f 100644 --- a/src/mtconnect/pipeline/json_mapper.hpp +++ b/src/mtconnect/pipeline/json_mapper.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/message_mapper.hpp b/src/mtconnect/pipeline/message_mapper.hpp index 1941fd57f..49edb6f51 100644 --- a/src/mtconnect/pipeline/message_mapper.hpp +++ b/src/mtconnect/pipeline/message_mapper.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/mtconnect_xml_transform.hpp b/src/mtconnect/pipeline/mtconnect_xml_transform.hpp index 4236cd467..269913336 100644 --- a/src/mtconnect/pipeline/mtconnect_xml_transform.hpp +++ b/src/mtconnect/pipeline/mtconnect_xml_transform.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/period_filter.hpp b/src/mtconnect/pipeline/period_filter.hpp index 4d2826382..6baf6545e 100644 --- a/src/mtconnect/pipeline/period_filter.hpp +++ b/src/mtconnect/pipeline/period_filter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/pipeline.hpp b/src/mtconnect/pipeline/pipeline.hpp index 1ee849233..c16b9e334 100644 --- a/src/mtconnect/pipeline/pipeline.hpp +++ b/src/mtconnect/pipeline/pipeline.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/pipeline_context.hpp b/src/mtconnect/pipeline/pipeline_context.hpp index bd451f150..42e55b554 100644 --- a/src/mtconnect/pipeline/pipeline_context.hpp +++ b/src/mtconnect/pipeline/pipeline_context.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/pipeline_contract.hpp b/src/mtconnect/pipeline/pipeline_contract.hpp index a46fc7deb..0066834c1 100644 --- a/src/mtconnect/pipeline/pipeline_contract.hpp +++ b/src/mtconnect/pipeline/pipeline_contract.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/response_document.cpp b/src/mtconnect/pipeline/response_document.cpp index aaa1b4066..419d4e6eb 100644 --- a/src/mtconnect/pipeline/response_document.cpp +++ b/src/mtconnect/pipeline/response_document.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/response_document.hpp b/src/mtconnect/pipeline/response_document.hpp index 1a915f001..f61016526 100644 --- a/src/mtconnect/pipeline/response_document.hpp +++ b/src/mtconnect/pipeline/response_document.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/shdr_token_mapper.cpp b/src/mtconnect/pipeline/shdr_token_mapper.cpp index 9af7bde7f..a31961e89 100644 --- a/src/mtconnect/pipeline/shdr_token_mapper.cpp +++ b/src/mtconnect/pipeline/shdr_token_mapper.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/shdr_token_mapper.hpp b/src/mtconnect/pipeline/shdr_token_mapper.hpp index 23f45a9dc..f12c192d6 100644 --- a/src/mtconnect/pipeline/shdr_token_mapper.hpp +++ b/src/mtconnect/pipeline/shdr_token_mapper.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/shdr_tokenizer.hpp b/src/mtconnect/pipeline/shdr_tokenizer.hpp index 5512d7ca9..a9c3d31f0 100644 --- a/src/mtconnect/pipeline/shdr_tokenizer.hpp +++ b/src/mtconnect/pipeline/shdr_tokenizer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/timestamp_extractor.hpp b/src/mtconnect/pipeline/timestamp_extractor.hpp index 65f839d21..2cddc792e 100644 --- a/src/mtconnect/pipeline/timestamp_extractor.hpp +++ b/src/mtconnect/pipeline/timestamp_extractor.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/topic_mapper.hpp b/src/mtconnect/pipeline/topic_mapper.hpp index 3d0067713..7aa52887e 100644 --- a/src/mtconnect/pipeline/topic_mapper.hpp +++ b/src/mtconnect/pipeline/topic_mapper.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/transform.hpp b/src/mtconnect/pipeline/transform.hpp index 917237bc3..6fbf9d3a5 100644 --- a/src/mtconnect/pipeline/transform.hpp +++ b/src/mtconnect/pipeline/transform.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/pipeline/upcase_value.hpp b/src/mtconnect/pipeline/upcase_value.hpp index b95bb24ad..fae0d1a42 100644 --- a/src/mtconnect/pipeline/upcase_value.hpp +++ b/src/mtconnect/pipeline/upcase_value.hpp @@ -1,4 +1,4 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/printer/json_printer.cpp b/src/mtconnect/printer/json_printer.cpp index 1108d0878..2720d5eaa 100644 --- a/src/mtconnect/printer/json_printer.cpp +++ b/src/mtconnect/printer/json_printer.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -47,8 +47,8 @@ namespace mtconnect::printer { using namespace device_model; using namespace rapidjson; - JsonPrinter::JsonPrinter(uint32_t jsonVersion, bool pretty) - : Printer(pretty), m_jsonVersion(jsonVersion) + JsonPrinter::JsonPrinter(uint32_t jsonVersion, bool pretty, bool validation) + : Printer(pretty, validation), m_jsonVersion(jsonVersion) { NAMED_SCOPE("JsonPrinter::JsonPrinter"); char appVersion[32] = {0}; @@ -60,7 +60,8 @@ namespace mtconnect::printer { template inline void header(AutoJsonObject &obj, const string &version, const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, - const string &schemaVersion, const string modelChangeTime) + const string &schemaVersion, const string modelChangeTime, + bool validation) { obj.AddPairs("version", version, "creationTime", getCurrentTime(GMT), "testIndicator", false, "instanceId", instanceId, "sender", hostname, "schemaVersion", schemaVersion); @@ -69,6 +70,9 @@ namespace mtconnect::printer { obj.AddPairs("deviceModelChangeTime", modelChangeTime); if (bufferSize > 0) obj.AddPairs("bufferSize", bufferSize); + if (validation) + obj.AddPairs("validation", true); + } template @@ -76,9 +80,10 @@ namespace mtconnect::printer { const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetBufferSize, const unsigned int assetCount, const string &schemaVersion, - const string modelChangeTime) + const string modelChangeTime, + const bool validation) { - header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime); + header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, validation); obj.AddPairs("assetBufferSize", assetBufferSize, "assetCount", assetCount); } @@ -87,9 +92,10 @@ namespace mtconnect::printer { const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSequence, const uint64_t firstSequence, const uint64_t lastSequence, const string &schemaVersion, - const string modelChangeTime) + const string modelChangeTime, + const bool validation) { - header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime); + header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, validation); obj.AddPairs("nextSequence", nextSequence, "lastSequence", lastSequence, "firstSequence", firstSequence); } @@ -123,7 +129,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); header(obj, m_version, m_senderName, instanceId, bufferSize, *m_schemaVersion, - m_modelChangeTime); + m_modelChangeTime, m_validation); } { if (m_jsonVersion > 1) @@ -180,7 +186,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); probeAssetHeader(obj, m_version, m_senderName, instanceId, bufferSize, assetBufferSize, - assetCount, *m_schemaVersion, m_modelChangeTime); + assetCount, *m_schemaVersion, m_modelChangeTime, m_validation); } { obj.Key("Devices"); @@ -207,7 +213,8 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); probeAssetHeader(obj, m_version, m_senderName, instanceId, 0, bufferSize, assetCount, - *m_schemaVersion, m_modelChangeTime); + *m_schemaVersion, m_modelChangeTime, + m_validation); } { obj.Key("Assets"); @@ -405,7 +412,8 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); streamHeader(obj, m_version, m_senderName, instanceId, bufferSize, nextSeq, firstSeq, - lastSeq, *m_schemaVersion, m_modelChangeTime); + lastSeq, *m_schemaVersion, m_modelChangeTime, + m_validation); } { diff --git a/src/mtconnect/printer/json_printer.hpp b/src/mtconnect/printer/json_printer.hpp index 2a1e4ea96..fd392133a 100644 --- a/src/mtconnect/printer/json_printer.hpp +++ b/src/mtconnect/printer/json_printer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,7 +27,7 @@ namespace mtconnect::printer { class AGENT_LIB_API JsonPrinter : public Printer { public: - JsonPrinter(uint32_t jsonVersion, bool pretty = false); + JsonPrinter(uint32_t jsonVersion, bool pretty = false, bool validation = false); ~JsonPrinter() override = default; std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, diff --git a/src/mtconnect/printer/json_printer_helper.hpp b/src/mtconnect/printer/json_printer_helper.hpp index e8bb39b00..61b843e33 100644 --- a/src/mtconnect/printer/json_printer_helper.hpp +++ b/src/mtconnect/printer/json_printer_helper.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/printer/printer.hpp b/src/mtconnect/printer/printer.hpp index cfc0bd270..4e39cb0a8 100644 --- a/src/mtconnect/printer/printer.hpp +++ b/src/mtconnect/printer/printer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -49,7 +49,7 @@ namespace mtconnect { public: /// @brief construct a printer /// @param pretty `true` if content should be pretty printed - Printer(bool pretty = false) : m_pretty(pretty) {} + Printer(bool pretty = false, bool validation = false) : m_pretty(pretty), m_validation(validation) {} virtual ~Printer() = default; /// @brief Generate an MTConnect Error document @@ -145,9 +145,19 @@ namespace mtconnect { const_cast(this)->m_schemaVersion.emplace(ver); } } + + /// @brief Get validation header flag state + /// @returns validation state + bool getValidation() const { return m_validation; } + + /// @brief sets validation state + /// @param validation the validation state + void setValidation(bool v) { m_validation = v; } + protected: - bool m_pretty; + bool m_pretty; //< Turns pretty printing on + bool m_validation; //< Sets validation flag in header std::string m_modelChangeTime; std::optional m_schemaVersion; std::string m_senderName {"localhost"}; diff --git a/src/mtconnect/printer/xml_helper.hpp b/src/mtconnect/printer/xml_helper.hpp index 94eac2d27..e1758ae55 100644 --- a/src/mtconnect/printer/xml_helper.hpp +++ b/src/mtconnect/printer/xml_helper.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/printer/xml_printer.cpp b/src/mtconnect/printer/xml_printer.cpp index bb37976cd..d495de620 100644 --- a/src/mtconnect/printer/xml_printer.cpp +++ b/src/mtconnect/printer/xml_printer.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -100,7 +100,7 @@ namespace mtconnect::printer { xmlBufferPtr m_buf; }; - XmlPrinter::XmlPrinter(bool pretty) : Printer(pretty) { NAMED_SCOPE("xml.printer"); } + XmlPrinter::XmlPrinter(bool pretty, bool validation) : Printer(pretty, validation) { NAMED_SCOPE("xml.printer"); } void XmlPrinter::addDevicesNamespace(const std::string &urn, const std::string &location, const std::string &prefix) @@ -660,6 +660,9 @@ namespace mtconnect::printer { addAttribute(writer, "sender", m_senderName); addAttribute(writer, "instanceId", to_string(instanceId)); + + if (m_validation) + addAttribute(writer, "instanceId", "true"s); char version[32] = {0}; sprintf(version, "%d.%d.%d.%d", AGENT_VERSION_MAJOR, AGENT_VERSION_MINOR, AGENT_VERSION_PATCH, diff --git a/src/mtconnect/printer/xml_printer.hpp b/src/mtconnect/printer/xml_printer.hpp index 266db039b..f1f6910f9 100644 --- a/src/mtconnect/printer/xml_printer.hpp +++ b/src/mtconnect/printer/xml_printer.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,7 +40,7 @@ namespace mtconnect { class AGENT_LIB_API XmlPrinter : public Printer { public: - XmlPrinter(bool pretty = false); + XmlPrinter(bool pretty = false, bool validation = false); ~XmlPrinter() override = default; std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, diff --git a/src/mtconnect/printer/xml_printer_helper.hpp b/src/mtconnect/printer/xml_printer_helper.hpp index 64eab3aa1..3ac60e91a 100644 --- a/src/mtconnect/printer/xml_printer_helper.hpp +++ b/src/mtconnect/printer/xml_printer_helper.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/embedded.cpp b/src/mtconnect/ruby/embedded.cpp index 6c5538cc8..4942b6885 100644 --- a/src/mtconnect/ruby/embedded.cpp +++ b/src/mtconnect/ruby/embedded.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/embedded.hpp b/src/mtconnect/ruby/embedded.hpp index 7caec3103..38a5a1102 100644 --- a/src/mtconnect/ruby/embedded.hpp +++ b/src/mtconnect/ruby/embedded.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_agent.hpp b/src/mtconnect/ruby/ruby_agent.hpp index 00da26c58..954fff2da 100644 --- a/src/mtconnect/ruby/ruby_agent.hpp +++ b/src/mtconnect/ruby/ruby_agent.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_entity.hpp b/src/mtconnect/ruby/ruby_entity.hpp index 6ba905097..6302afe4d 100644 --- a/src/mtconnect/ruby/ruby_entity.hpp +++ b/src/mtconnect/ruby/ruby_entity.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_observation.hpp b/src/mtconnect/ruby/ruby_observation.hpp index a41586214..df0dec968 100644 --- a/src/mtconnect/ruby/ruby_observation.hpp +++ b/src/mtconnect/ruby/ruby_observation.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_pipeline.hpp b/src/mtconnect/ruby/ruby_pipeline.hpp index beb10a3c4..0e1bf5312 100644 --- a/src/mtconnect/ruby/ruby_pipeline.hpp +++ b/src/mtconnect/ruby/ruby_pipeline.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_smart_ptr.hpp b/src/mtconnect/ruby/ruby_smart_ptr.hpp index 97e34f3d3..a8c23106f 100644 --- a/src/mtconnect/ruby/ruby_smart_ptr.hpp +++ b/src/mtconnect/ruby/ruby_smart_ptr.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_transform.hpp b/src/mtconnect/ruby/ruby_transform.hpp index 4dc9c4cdf..94693b29d 100644 --- a/src/mtconnect/ruby/ruby_transform.hpp +++ b/src/mtconnect/ruby/ruby_transform.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_type.hpp b/src/mtconnect/ruby/ruby_type.hpp index 34641cd3b..087b0e8fd 100644 --- a/src/mtconnect/ruby/ruby_type.hpp +++ b/src/mtconnect/ruby/ruby_type.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/ruby/ruby_vm.hpp b/src/mtconnect/ruby/ruby_vm.hpp index 35d8dc065..faba18f23 100644 --- a/src/mtconnect/ruby/ruby_vm.hpp +++ b/src/mtconnect/ruby/ruby_vm.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp index 6a2f54e59..b28b72d0f 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp index 3b89b2cea..e94d01f55 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/cached_file.hpp b/src/mtconnect/sink/rest_sink/cached_file.hpp index da2ca52f5..40efea4fb 100644 --- a/src/mtconnect/sink/rest_sink/cached_file.hpp +++ b/src/mtconnect/sink/rest_sink/cached_file.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/file_cache.cpp b/src/mtconnect/sink/rest_sink/file_cache.cpp index d230a490e..07d31e182 100644 --- a/src/mtconnect/sink/rest_sink/file_cache.cpp +++ b/src/mtconnect/sink/rest_sink/file_cache.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/file_cache.hpp b/src/mtconnect/sink/rest_sink/file_cache.hpp index 5ee445a7c..f5125ccd3 100644 --- a/src/mtconnect/sink/rest_sink/file_cache.hpp +++ b/src/mtconnect/sink/rest_sink/file_cache.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/parameter.hpp b/src/mtconnect/sink/rest_sink/parameter.hpp index 9eea8feeb..cb2879c34 100644 --- a/src/mtconnect/sink/rest_sink/parameter.hpp +++ b/src/mtconnect/sink/rest_sink/parameter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index 5271c791c..9a24e2239 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/response.hpp b/src/mtconnect/sink/rest_sink/response.hpp index f8ae3c98e..a67bdbe6b 100644 --- a/src/mtconnect/sink/rest_sink/response.hpp +++ b/src/mtconnect/sink/rest_sink/response.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 7f82f797a..4b8167b9c 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/rest_service.hpp b/src/mtconnect/sink/rest_sink/rest_service.hpp index 3e8091cb0..51505fd51 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.hpp +++ b/src/mtconnect/sink/rest_sink/rest_service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index 10d852a98..ca8bdf38d 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/server.cpp b/src/mtconnect/sink/rest_sink/server.cpp index 93b387e1f..7071c02ee 100644 --- a/src/mtconnect/sink/rest_sink/server.cpp +++ b/src/mtconnect/sink/rest_sink/server.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/server.hpp b/src/mtconnect/sink/rest_sink/server.hpp index 07c5c4b59..d72fd1764 100644 --- a/src/mtconnect/sink/rest_sink/server.hpp +++ b/src/mtconnect/sink/rest_sink/server.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index a6443f782..c4ed9041a 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index 2ddd38e33..52651e384 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/session_impl.hpp b/src/mtconnect/sink/rest_sink/session_impl.hpp index 0d811a84a..27be34970 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.hpp +++ b/src/mtconnect/sink/rest_sink/session_impl.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/rest_sink/tls_dector.hpp b/src/mtconnect/sink/rest_sink/tls_dector.hpp index 197e9a91b..cf8065899 100644 --- a/src/mtconnect/sink/rest_sink/tls_dector.hpp +++ b/src/mtconnect/sink/rest_sink/tls_dector.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/sink.cpp b/src/mtconnect/sink/sink.cpp index 4fb757485..1a65d10f9 100644 --- a/src/mtconnect/sink/sink.cpp +++ b/src/mtconnect/sink/sink.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/sink/sink.hpp b/src/mtconnect/sink/sink.hpp index 1e517284d..c06d0e1c4 100644 --- a/src/mtconnect/sink/sink.hpp +++ b/src/mtconnect/sink/sink.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/adapter.hpp b/src/mtconnect/source/adapter/adapter.hpp index f27ffc03a..7052d6d87 100644 --- a/src/mtconnect/source/adapter/adapter.hpp +++ b/src/mtconnect/source/adapter/adapter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/adapter_pipeline.cpp b/src/mtconnect/source/adapter/adapter_pipeline.cpp index 741cabdfb..16a3dd505 100644 --- a/src/mtconnect/source/adapter/adapter_pipeline.cpp +++ b/src/mtconnect/source/adapter/adapter_pipeline.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/adapter_pipeline.hpp b/src/mtconnect/source/adapter/adapter_pipeline.hpp index 26aa8838b..a42a49112 100644 --- a/src/mtconnect/source/adapter/adapter_pipeline.hpp +++ b/src/mtconnect/source/adapter/adapter_pipeline.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/agent_adapter.cpp b/src/mtconnect/source/adapter/agent_adapter/agent_adapter.cpp index b54ae9d7a..afc34b151 100644 --- a/src/mtconnect/source/adapter/agent_adapter/agent_adapter.cpp +++ b/src/mtconnect/source/adapter/agent_adapter/agent_adapter.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/agent_adapter.hpp b/src/mtconnect/source/adapter/agent_adapter/agent_adapter.hpp index fb97f9e0d..aed804f63 100644 --- a/src/mtconnect/source/adapter/agent_adapter/agent_adapter.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/agent_adapter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/http_session.hpp b/src/mtconnect/source/adapter/agent_adapter/http_session.hpp index 9f97d8cb0..9f887b8d0 100644 --- a/src/mtconnect/source/adapter/agent_adapter/http_session.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/http_session.hpp @@ -1,6 +1,6 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/https_session.hpp b/src/mtconnect/source/adapter/agent_adapter/https_session.hpp index ba60d7ddd..a00323016 100644 --- a/src/mtconnect/source/adapter/agent_adapter/https_session.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/https_session.hpp @@ -1,6 +1,6 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/session.hpp b/src/mtconnect/source/adapter/agent_adapter/session.hpp index 55e3699a2..7a321ad60 100644 --- a/src/mtconnect/source/adapter/agent_adapter/session.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/session.hpp @@ -1,6 +1,6 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/agent_adapter/session_impl.hpp b/src/mtconnect/source/adapter/agent_adapter/session_impl.hpp index 3e9c5e7da..41745fb7e 100644 --- a/src/mtconnect/source/adapter/agent_adapter/session_impl.hpp +++ b/src/mtconnect/source/adapter/agent_adapter/session_impl.hpp @@ -1,6 +1,6 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp index d2a9eb7bb..67fda0747 100644 --- a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp +++ b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.hpp b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.hpp index 991a2b3c1..b0c932e66 100644 --- a/src/mtconnect/source/adapter/mqtt/mqtt_adapter.hpp +++ b/src/mtconnect/source/adapter/mqtt/mqtt_adapter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/connector.cpp b/src/mtconnect/source/adapter/shdr/connector.cpp index 216d4c894..fb7f5979d 100644 --- a/src/mtconnect/source/adapter/shdr/connector.cpp +++ b/src/mtconnect/source/adapter/shdr/connector.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/connector.hpp b/src/mtconnect/source/adapter/shdr/connector.hpp index 638c0e9dc..d8cd727a8 100644 --- a/src/mtconnect/source/adapter/shdr/connector.hpp +++ b/src/mtconnect/source/adapter/shdr/connector.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp b/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp index 161eb13bc..366b4e9b1 100644 --- a/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp +++ b/src/mtconnect/source/adapter/shdr/shdr_adapter.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/shdr_adapter.hpp b/src/mtconnect/source/adapter/shdr/shdr_adapter.hpp index d04519a26..4b40f514c 100644 --- a/src/mtconnect/source/adapter/shdr/shdr_adapter.hpp +++ b/src/mtconnect/source/adapter/shdr/shdr_adapter.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/shdr_pipeline.cpp b/src/mtconnect/source/adapter/shdr/shdr_pipeline.cpp index 2a2f6d55a..45116061e 100644 --- a/src/mtconnect/source/adapter/shdr/shdr_pipeline.cpp +++ b/src/mtconnect/source/adapter/shdr/shdr_pipeline.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/adapter/shdr/shdr_pipeline.hpp b/src/mtconnect/source/adapter/shdr/shdr_pipeline.hpp index 5962834f1..f975ee4f2 100644 --- a/src/mtconnect/source/adapter/shdr/shdr_pipeline.hpp +++ b/src/mtconnect/source/adapter/shdr/shdr_pipeline.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/error_code.hpp b/src/mtconnect/source/error_code.hpp index 32f7b4bd2..af3164bb5 100644 --- a/src/mtconnect/source/error_code.hpp +++ b/src/mtconnect/source/error_code.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/loopback_source.cpp b/src/mtconnect/source/loopback_source.cpp index f0b8b69d4..12bb4c729 100644 --- a/src/mtconnect/source/loopback_source.cpp +++ b/src/mtconnect/source/loopback_source.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/loopback_source.hpp b/src/mtconnect/source/loopback_source.hpp index 64d9af242..e12ee2282 100644 --- a/src/mtconnect/source/loopback_source.hpp +++ b/src/mtconnect/source/loopback_source.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/source.cpp b/src/mtconnect/source/source.cpp index 5cc0322c3..eb1f8c59a 100644 --- a/src/mtconnect/source/source.cpp +++ b/src/mtconnect/source/source.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/source/source.hpp b/src/mtconnect/source/source.hpp index cdacfb9f5..4debdafb6 100644 --- a/src/mtconnect/source/source.hpp +++ b/src/mtconnect/source/source.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/utilities.cpp b/src/mtconnect/utilities.cpp index 0a6c8eba1..e9d48a60e 100644 --- a/src/mtconnect/utilities.cpp +++ b/src/mtconnect/utilities.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/utilities.hpp b/src/mtconnect/utilities.hpp index adf596976..230f7a660 100644 --- a/src/mtconnect/utilities.hpp +++ b/src/mtconnect/utilities.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp new file mode 100644 index 000000000..24af87c85 --- /dev/null +++ b/src/mtconnect/validation/observation_validations.hpp @@ -0,0 +1,39 @@ + Validation ControlledVocabularies { + {"ACTUATOR_STATE", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"AVAILABILITY", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, + {"AXIS_COUPLING", {{"TANDEM", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}, {"SLAVE", 0}}}, + {"AXIS_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"AXIS_STATE", {{"HOME", 0}, {"TRAVEL", 0}, {"PARKED", 0}, {"STOPPED", 0}}}, + {"CHUCK_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"CHUCK_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, + {"CONTROLLER_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"EDIT", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, + {"CONTROLLER_MODE_OVERRIDE", {{"ON", 0}, {"OFF", 0}}}, + {"DIRECTION", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, + {"DOOR_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, + {"EMERGENCY_STOP", {{"ARMED", 0}, {"TRIGGERED", 0}}}, + {"END_OF_BAR", {{"YES", 0}, {"NO", 0}}}, + {"EQUIPMENT_MODE", {{"ON", 0}, {"OFF", 0}}}, + {"EXECUTION", {{"READY", 0}, {"ACTIVE", 0}, {"INTERRUPTED", 0}, {"FEED_HOLD", 0}, {"STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"PROGRAM_STOPPED", 0}, {"PROGRAM_COMPLETED", 0}, {"WAIT", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, + {"FUNCTIONAL_MODE", {{"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}, {"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}}}, + {"PART_DETECT", {{"PRESENT", 0}, {"NOT_PRESENT", 0}}}, + {"PATH_MODE", {{"INDEPENDENT", 0}, {"MASTER", 0}, {"SYNCHRONOUS", 0}, {"MIRROR", 0}}}, + {"POWER_STATE", {{"ON", 0}, {"OFF", 0}}}, + {"POWER_STATUS", {{"ON", SCHEMA_VERSION(1, 1)}, {"OFF", SCHEMA_VERSION(1, 1)}}}, + {"PROGRAM_EDIT", {{"ACTIVE", 0}, {"READY", 0}, {"NOT_READY", 0}}}, + {"PROGRAM_LOCATION_TYPE", {{"LOCAL", 0}, {"EXTERNAL", 0}}}, + {"ROTARY_MODE", {{"SPINDLE", 0}, {"INDEX", 0}, {"CONTOUR", 0}}}, + {"SPINDLE_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"WAIT_STATE", {{"POWERING_UP", 0}, {"POWERING_DOWN", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}, {"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"SECONDARY_PROCESS", 0}, {"PAUSING", 0}, {"RESUMING", 0}}}, + {"PART_STATUS", {{"PASS", 0}, {"FAIL", 0}}}, + {"CONNECTION_STATUS", {{"CLOSED", 0}, {"LISTEN", 0}, {"ESTABLISHED", 0}}}, + {"PART_PROCESSING_STATE", {{"NEEDS_PROCESSING", 0}, {"IN_PROCESS", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"WAITING_FOR_TRANSIT", 0}, {"IN_TRANSIT", 0}, {"TRANSIT_COMPLETE", 0}}}, + {"PROCESS_STATE", {{"INITIALIZING", 0}, {"READY", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INTERRUPTED", 0}, {"ABORTED", 0}}}, + {"VALVE_STATE", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, + {"LOCK_STATE", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, + {"OPERATING_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, + {"PART_COUNT_TYPE", {{"EACH", 0}, {"BATCH", 0}}}, + {"LEAK_DETECT", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, + {"BATTERY_STATE", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGING", 0}, {"DISCHARGED", 0}}}, + {"ADAPTER_URI", {{"PASS", 0}, {"FAIL", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"UNDEFINED", 0}}}, + {"UNCERTAINTY_TYPE", {{"COMBINED", 0}, {"MEAN", 0}}} + }; diff --git a/src/mtconnect/validation/observations.cpp b/src/mtconnect/validation/observations.cpp new file mode 100644 index 000000000..4f2825a5d --- /dev/null +++ b/src/mtconnect/validation/observations.cpp @@ -0,0 +1,22 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "observations.hpp" + +namespace mtconnect::validation::observations { +#include "observation_validations.hpp" +} diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp new file mode 100644 index 000000000..f540d6131 --- /dev/null +++ b/src/mtconnect/validation/observations.hpp @@ -0,0 +1,29 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include "../utilities.hpp" + +#include +#include + +namespace mtconnect::validation::observations { + using Validation = std::unordered_map>; + + extern Validation ControlledVocabularies; +} diff --git a/src/mtconnect/version.cpp b/src/mtconnect/version.cpp index b27f769f2..8a082fb36 100644 --- a/src/mtconnect/version.cpp +++ b/src/mtconnect/version.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/adapter_test.cpp b/test_package/adapter_test.cpp index 8fa5eba8b..58712ec98 100644 --- a/test_package/adapter_test.cpp +++ b/test_package/adapter_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/agent_adapter_test.cpp b/test_package/agent_adapter_test.cpp index 81dc48b36..bad9f9600 100644 --- a/test_package/agent_adapter_test.cpp +++ b/test_package/agent_adapter_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/agent_device_test.cpp b/test_package/agent_device_test.cpp index 02a131dfa..da174ed81 100644 --- a/test_package/agent_device_test.cpp +++ b/test_package/agent_device_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 12ab33ea8..0021a7718 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/agent_test_helper.cpp b/test_package/agent_test_helper.cpp index 8cc85fba0..c1dd2ccb3 100644 --- a/test_package/agent_test_helper.cpp +++ b/test_package/agent_test_helper.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/agent_test_helper.hpp b/test_package/agent_test_helper.hpp index 39c857883..13c14fc94 100644 --- a/test_package/agent_test_helper.hpp +++ b/test_package/agent_test_helper.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/asset_buffer_test.cpp b/test_package/asset_buffer_test.cpp index 54d5c4076..92efefea8 100644 --- a/test_package/asset_buffer_test.cpp +++ b/test_package/asset_buffer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/asset_hash_test.cpp b/test_package/asset_hash_test.cpp index 6d5529e48..ae17a1665 100644 --- a/test_package/asset_hash_test.cpp +++ b/test_package/asset_hash_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/asset_test.cpp b/test_package/asset_test.cpp index 49e383f31..f5fd92825 100644 --- a/test_package/asset_test.cpp +++ b/test_package/asset_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/change_observer_test.cpp b/test_package/change_observer_test.cpp index e3f90663a..b7501a6c8 100644 --- a/test_package/change_observer_test.cpp +++ b/test_package/change_observer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/checkpoint_test.cpp b/test_package/checkpoint_test.cpp index e810b8d31..f874ae5c4 100644 --- a/test_package/checkpoint_test.cpp +++ b/test_package/checkpoint_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/circular_buffer_test.cpp b/test_package/circular_buffer_test.cpp index ca19a6ea2..4e935c94b 100644 --- a/test_package/circular_buffer_test.cpp +++ b/test_package/circular_buffer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/component_parameters_test.cpp b/test_package/component_parameters_test.cpp index 6df0c76db..076175db9 100644 --- a/test_package/component_parameters_test.cpp +++ b/test_package/component_parameters_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/component_test.cpp b/test_package/component_test.cpp index 53c8c583c..b4b8c1a87 100644 --- a/test_package/component_test.cpp +++ b/test_package/component_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/composition_test.cpp b/test_package/composition_test.cpp index b9e75879b..4501ac3f4 100644 --- a/test_package/composition_test.cpp +++ b/test_package/composition_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/config_parser_test.cpp b/test_package/config_parser_test.cpp index 2bc8f9872..fab7e9ad6 100644 --- a/test_package/config_parser_test.cpp +++ b/test_package/config_parser_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/config_test.cpp b/test_package/config_test.cpp index d9b0d4b9b..29913b225 100644 --- a/test_package/config_test.cpp +++ b/test_package/config_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/connector_test.cpp b/test_package/connector_test.cpp index 480179032..e40c351d8 100644 --- a/test_package/connector_test.cpp +++ b/test_package/connector_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/coordinate_system_test.cpp b/test_package/coordinate_system_test.cpp index 3b9c380a0..4a4f56535 100644 --- a/test_package/coordinate_system_test.cpp +++ b/test_package/coordinate_system_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/cutting_tool_test.cpp b/test_package/cutting_tool_test.cpp index 5f1c04ef1..4647cc036 100644 --- a/test_package/cutting_tool_test.cpp +++ b/test_package/cutting_tool_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/data_item_mapping_test.cpp b/test_package/data_item_mapping_test.cpp index 56f518b8a..295586900 100644 --- a/test_package/data_item_mapping_test.cpp +++ b/test_package/data_item_mapping_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/data_item_test.cpp b/test_package/data_item_test.cpp index 178bb1ca0..5e88dc6f1 100644 --- a/test_package/data_item_test.cpp +++ b/test_package/data_item_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/data_set_test.cpp b/test_package/data_set_test.cpp index 4c2fd43c6..24566788a 100644 --- a/test_package/data_set_test.cpp +++ b/test_package/data_set_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/device_test.cpp b/test_package/device_test.cpp index a0a728922..6bb14a651 100644 --- a/test_package/device_test.cpp +++ b/test_package/device_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/duplicate_filter_test.cpp b/test_package/duplicate_filter_test.cpp index e88ee5900..744f43205 100644 --- a/test_package/duplicate_filter_test.cpp +++ b/test_package/duplicate_filter_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/embedded_ruby_test.cpp b/test_package/embedded_ruby_test.cpp index 2427dbc1d..5469a091b 100644 --- a/test_package/embedded_ruby_test.cpp +++ b/test_package/embedded_ruby_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/entity_parser_test.cpp b/test_package/entity_parser_test.cpp index c34a84858..ab752021d 100644 --- a/test_package/entity_parser_test.cpp +++ b/test_package/entity_parser_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/entity_printer_test.cpp b/test_package/entity_printer_test.cpp index 22dd514b9..2999fe1e3 100644 --- a/test_package/entity_printer_test.cpp +++ b/test_package/entity_printer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/entity_test.cpp b/test_package/entity_test.cpp index f10318fd5..88396d8de 100644 --- a/test_package/entity_test.cpp +++ b/test_package/entity_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/file_asset_test.cpp b/test_package/file_asset_test.cpp index a2d57c932..9b5a753e9 100644 --- a/test_package/file_asset_test.cpp +++ b/test_package/file_asset_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/file_cache_test.cpp b/test_package/file_cache_test.cpp index 6d453f781..5e916fd28 100644 --- a/test_package/file_cache_test.cpp +++ b/test_package/file_cache_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/globals_test.cpp b/test_package/globals_test.cpp index 23c423393..48cdee99a 100644 --- a/test_package/globals_test.cpp +++ b/test_package/globals_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/http_server_test.cpp b/test_package/http_server_test.cpp index 07d69fb67..da52c633a 100644 --- a/test_package/http_server_test.cpp +++ b/test_package/http_server_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/image_file_test.cpp b/test_package/image_file_test.cpp index eca9fa5e8..9a1ebfe67 100644 --- a/test_package/image_file_test.cpp +++ b/test_package/image_file_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_helper.hpp b/test_package/json_helper.hpp index e23afcb76..5ec636147 100644 --- a/test_package/json_helper.hpp +++ b/test_package/json_helper.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_mapping_test.cpp b/test_package/json_mapping_test.cpp index baf6fa7e4..58398a123 100644 --- a/test_package/json_mapping_test.cpp +++ b/test_package/json_mapping_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_parser_test.cpp b/test_package/json_parser_test.cpp index 3995e78a4..5db25737f 100644 --- a/test_package/json_parser_test.cpp +++ b/test_package/json_parser_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_printer_asset_test.cpp b/test_package/json_printer_asset_test.cpp index 7f478b080..d2e61b8f6 100644 --- a/test_package/json_printer_asset_test.cpp +++ b/test_package/json_printer_asset_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_printer_error_test.cpp b/test_package/json_printer_error_test.cpp index 147ce7967..f4a2a7291 100644 --- a/test_package/json_printer_error_test.cpp +++ b/test_package/json_printer_error_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_printer_probe_test.cpp b/test_package/json_printer_probe_test.cpp index c3b6ed066..1760aea92 100644 --- a/test_package/json_printer_probe_test.cpp +++ b/test_package/json_printer_probe_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_printer_stream_test.cpp b/test_package/json_printer_stream_test.cpp index b00ed3b77..03b1fd8e2 100644 --- a/test_package/json_printer_stream_test.cpp +++ b/test_package/json_printer_stream_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/json_printer_test.cpp b/test_package/json_printer_test.cpp index 686ce425d..1fbb276f1 100644 --- a/test_package/json_printer_test.cpp +++ b/test_package/json_printer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/kinematics_test.cpp b/test_package/kinematics_test.cpp index 1dd927cb1..a2bf20d36 100644 --- a/test_package/kinematics_test.cpp +++ b/test_package/kinematics_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/mqtt_adapter_test.cpp b/test_package/mqtt_adapter_test.cpp index 9a14699be..2e2c4683f 100644 --- a/test_package/mqtt_adapter_test.cpp +++ b/test_package/mqtt_adapter_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/mqtt_isolated_test.cpp b/test_package/mqtt_isolated_test.cpp index 5b7ae824e..9789436c5 100644 --- a/test_package/mqtt_isolated_test.cpp +++ b/test_package/mqtt_isolated_test.cpp @@ -1,5 +1,5 @@ -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/mqtt_sink_2_test.cpp b/test_package/mqtt_sink_2_test.cpp index ea3de6dcb..93a8196d2 100644 --- a/test_package/mqtt_sink_2_test.cpp +++ b/test_package/mqtt_sink_2_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/mqtt_sink_test.cpp b/test_package/mqtt_sink_test.cpp index d8c30f7ae..f8a46e246 100644 --- a/test_package/mqtt_sink_test.cpp +++ b/test_package/mqtt_sink_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/mtconnect_xml_transform_test.cpp b/test_package/mtconnect_xml_transform_test.cpp index 2e44f6a22..226826e48 100644 --- a/test_package/mtconnect_xml_transform_test.cpp +++ b/test_package/mtconnect_xml_transform_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/observation_test.cpp b/test_package/observation_test.cpp index feb6a10d4..3040dfe31 100644 --- a/test_package/observation_test.cpp +++ b/test_package/observation_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/period_filter_test.cpp b/test_package/period_filter_test.cpp index e0adc5b19..02d5029ea 100644 --- a/test_package/period_filter_test.cpp +++ b/test_package/period_filter_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/pipeline_deliver_test.cpp b/test_package/pipeline_deliver_test.cpp index 4d611663f..3e632ee37 100644 --- a/test_package/pipeline_deliver_test.cpp +++ b/test_package/pipeline_deliver_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/pipeline_edit_test.cpp b/test_package/pipeline_edit_test.cpp index 130c09769..c5b68d90f 100644 --- a/test_package/pipeline_edit_test.cpp +++ b/test_package/pipeline_edit_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/qif_document_test.cpp b/test_package/qif_document_test.cpp index 269353f91..68097689f 100644 --- a/test_package/qif_document_test.cpp +++ b/test_package/qif_document_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/qname_test.cpp b/test_package/qname_test.cpp index 9462d1e0e..05ac55b35 100644 --- a/test_package/qname_test.cpp +++ b/test_package/qname_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/raw_material_test.cpp b/test_package/raw_material_test.cpp index 558dd262c..e7edecf6d 100644 --- a/test_package/raw_material_test.cpp +++ b/test_package/raw_material_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/references_test.cpp b/test_package/references_test.cpp index e81aba959..7d18c1148 100644 --- a/test_package/references_test.cpp +++ b/test_package/references_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/relationship_test.cpp b/test_package/relationship_test.cpp index c4feb60a6..b9ebf7f07 100644 --- a/test_package/relationship_test.cpp +++ b/test_package/relationship_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/response_document_test.cpp b/test_package/response_document_test.cpp index 6cc1dcaba..ae38d50e6 100644 --- a/test_package/response_document_test.cpp +++ b/test_package/response_document_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/routing_test.cpp b/test_package/routing_test.cpp index b26a86576..d4457f580 100644 --- a/test_package/routing_test.cpp +++ b/test_package/routing_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/sensor_configuration_test.cpp b/test_package/sensor_configuration_test.cpp index 1d94d46ab..eaf783b65 100644 --- a/test_package/sensor_configuration_test.cpp +++ b/test_package/sensor_configuration_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/shdr_tokenizer_test.cpp b/test_package/shdr_tokenizer_test.cpp index 8150df87a..76b754d43 100644 --- a/test_package/shdr_tokenizer_test.cpp +++ b/test_package/shdr_tokenizer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/solid_model_test.cpp b/test_package/solid_model_test.cpp index 169eea1ef..7cd6696a7 100644 --- a/test_package/solid_model_test.cpp +++ b/test_package/solid_model_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/specification_test.cpp b/test_package/specification_test.cpp index dff297813..3e3529fd6 100644 --- a/test_package/specification_test.cpp +++ b/test_package/specification_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/table_test.cpp b/test_package/table_test.cpp index 8da67faa2..215c8735c 100644 --- a/test_package/table_test.cpp +++ b/test_package/table_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/test_utilities.hpp b/test_package/test_utilities.hpp index 7fe6fea09..df1b0699e 100644 --- a/test_package/test_utilities.hpp +++ b/test_package/test_utilities.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/testadapter_service.cpp b/test_package/testadapter_service.cpp index 79f08bf74..23ae60b83 100644 --- a/test_package/testadapter_service.cpp +++ b/test_package/testadapter_service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/testadapter_service.hpp b/test_package/testadapter_service.hpp index 29ec1c06e..347324036 100644 --- a/test_package/testadapter_service.hpp +++ b/test_package/testadapter_service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/testsink_service.cpp b/test_package/testsink_service.cpp index 144ede526..245c9f595 100644 --- a/test_package/testsink_service.cpp +++ b/test_package/testsink_service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/testsink_service.hpp b/test_package/testsink_service.hpp index affd7c3f6..87b6d551e 100644 --- a/test_package/testsink_service.hpp +++ b/test_package/testsink_service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/timestamp_extractor_test.cpp b/test_package/timestamp_extractor_test.cpp index 49f05525d..dd355f17a 100644 --- a/test_package/timestamp_extractor_test.cpp +++ b/test_package/timestamp_extractor_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/tls_http_server_test.cpp b/test_package/tls_http_server_test.cpp index e141502a6..830d85f06 100644 --- a/test_package/tls_http_server_test.cpp +++ b/test_package/tls_http_server_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/topic_mapping_test.cpp b/test_package/topic_mapping_test.cpp index 8d862ed05..de279ac71 100644 --- a/test_package/topic_mapping_test.cpp +++ b/test_package/topic_mapping_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/unit_conversion_test.cpp b/test_package/unit_conversion_test.cpp index e52ee6e9e..2998ae54f 100644 --- a/test_package/unit_conversion_test.cpp +++ b/test_package/unit_conversion_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/url_parser_test.cpp b/test_package/url_parser_test.cpp index f36ebd026..bf7199a99 100644 --- a/test_package/url_parser_test.cpp +++ b/test_package/url_parser_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/xml_parser_test.cpp b/test_package/xml_parser_test.cpp index 85814ea55..f2c532b94 100644 --- a/test_package/xml_parser_test.cpp +++ b/test_package/xml_parser_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/test_package/xml_printer_test.cpp b/test_package/xml_printer_test.cpp index 354bfd238..feba4c780 100644 --- a/test_package/xml_printer_test.cpp +++ b/test_package/xml_printer_test.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2022, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); From d27338892923f4048229b6c83e9711b06f443284 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 5 Apr 2024 23:28:20 -0400 Subject: [PATCH 065/128] first version of validation transform with pipeline --- CMakeLists.txt | 6 +- agent_lib/CMakeLists.txt | 5 +- src/mtconnect/pipeline/period_filter.hpp | 2 +- src/mtconnect/pipeline/validator.hpp | 99 ++++++++++++ src/mtconnect/printer/xml_printer.cpp | 2 +- .../source/adapter/adapter_pipeline.cpp | 5 + src/mtconnect/source/loopback_source.cpp | 7 + .../validation/observation_validations.hpp | 104 ++++++++++++- src/mtconnect/validation/observations.hpp | 2 +- test_package/CMakeLists.txt | 1 + test_package/observation_validation_test.cpp | 143 ++++++++++++++++++ 11 files changed, 366 insertions(+), 10 deletions(-) create mode 100644 src/mtconnect/pipeline/validator.hpp create mode 100644 test_package/observation_validation_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4509ec039..81d1e1c71 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,9 @@ # The version number. set(AGENT_VERSION_MAJOR 2) -set(AGENT_VERSION_MINOR 4) +set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) -set(AGENT_VERSION_BUILD 3) -set(AGENT_VERSION_RC "") +set(AGENT_VERSION_BUILD 0) +set(AGENT_VERSION_RC "RC1") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index 028b3a101..6f5a9e4fe 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -183,6 +183,7 @@ set(AGENT_SOURCES "${SOURCE_DIR}/pipeline/topic_mapper.hpp" "${SOURCE_DIR}/pipeline/transform.hpp" "${SOURCE_DIR}/pipeline/upcase_value.hpp" + "${SOURCE_DIR}/pipeline/validator.hpp" # src/pipeline SOURCE_FILES_ONLY @@ -244,12 +245,12 @@ set(AGENT_SOURCES # src/sink/mqtt_sink HEADER_FILE_ONLY "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.hpp" - "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.hpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.hpp" #src/sink/mqtt_sink SOURCE_FILES_ONLY "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" - "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.cpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.cpp" # src/sink/rest_sink HEADER_FILE_ONLY diff --git a/src/mtconnect/pipeline/period_filter.hpp b/src/mtconnect/pipeline/period_filter.hpp index 6baf6545e..9073e8552 100644 --- a/src/mtconnect/pipeline/period_filter.hpp +++ b/src/mtconnect/pipeline/period_filter.hpp @@ -127,7 +127,7 @@ namespace mtconnect::pipeline { } } - return next(obs); + return next(std::move(obs)); } protected: diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp new file mode 100644 index 000000000..995200c94 --- /dev/null +++ b/src/mtconnect/pipeline/validator.hpp @@ -0,0 +1,99 @@ +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include +#include + +#include "mtconnect/config.hpp" +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/observation/observation.hpp" +#include "mtconnect/validation/observations.hpp" +#include "transform.hpp" + +namespace mtconnect::pipeline { + using namespace entity; + + /// @brief Map a token list to data items or asset types + class AGENT_LIB_API Validator : public Transform + { + public: + Validator(const Validator &) = default; + Validator(PipelineContextPtr context) + : Transform("Validator"), + m_contract(context->m_contract.get()) + { + m_guard = TypeGuard(RUN) || TypeGuard(SKIP); + } + + EntityPtr operator()(entity::EntityPtr &&entity) override + { + using namespace observation; + using namespace mtconnect::validation::observations; + auto evt = std::dynamic_pointer_cast(entity); + + auto di = evt->getDataItem(); + auto &type = di->getType(); + auto &value = evt->getValue(); + + if (value == "UNAVAILABLE") + { + evt->setProperty("quality", std::string("VALID")); + } + else + { + // Optimize + auto vocab = ControlledVocabularies.find(type); + if (vocab != ControlledVocabularies.end()) + { + auto &lits = vocab->second; + if (lits.size() != 0) + { + auto lit = lits.find(value); + if (lit != lits.end()) + { + evt->setProperty("quality", std::string("VALID")); + // Check for deprecated + } + else + { + evt->setProperty("quality", std::string("INVALID")); + // Log once + LOG(warning) << "Invalid value for '" << type << "' " << evt->getValue(); + } + } + else + { + evt->setProperty("quality", std::string("VALID")); + } + } + else + { + evt->setProperty("quality", std::string("UNVERIFIABLE")); + } + } + + return next(std::move(evt)); + } + + protected: + // Logging Context + std::set m_logOnce; + PipelineContract *m_contract; + std::unordered_map m_dataItemMap; + }; +} // namespace mtconnect::pipeline diff --git a/src/mtconnect/printer/xml_printer.cpp b/src/mtconnect/printer/xml_printer.cpp index d495de620..f5b6ef574 100644 --- a/src/mtconnect/printer/xml_printer.cpp +++ b/src/mtconnect/printer/xml_printer.cpp @@ -662,7 +662,7 @@ namespace mtconnect::printer { addAttribute(writer, "instanceId", to_string(instanceId)); if (m_validation) - addAttribute(writer, "instanceId", "true"s); + addAttribute(writer, "validation", "true"s); char version[32] = {0}; sprintf(version, "%d.%d.%d.%d", AGENT_VERSION_MAJOR, AGENT_VERSION_MINOR, AGENT_VERSION_PATCH, diff --git a/src/mtconnect/source/adapter/adapter_pipeline.cpp b/src/mtconnect/source/adapter/adapter_pipeline.cpp index 16a3dd505..615b47412 100644 --- a/src/mtconnect/source/adapter/adapter_pipeline.cpp +++ b/src/mtconnect/source/adapter/adapter_pipeline.cpp @@ -28,6 +28,7 @@ #include "mtconnect/pipeline/timestamp_extractor.hpp" #include "mtconnect/pipeline/topic_mapper.hpp" #include "mtconnect/pipeline/upcase_value.hpp" +#include "mtconnect/pipeline/validator.hpp" #include "mtconnect/source/adapter/adapter.hpp" using namespace std; @@ -138,6 +139,10 @@ namespace mtconnect { // Convert values if (IsOptionSet(m_options, configuration::ConversionRequired)) next = next->bind(make_shared()); + + // Validate Values + if (IsOptionSet(m_options, configuration::Validation)) + next = next->bind(make_shared(m_context)); // Filter dups, by delta, and by period next = next->bind(make_shared(m_context)); diff --git a/src/mtconnect/source/loopback_source.cpp b/src/mtconnect/source/loopback_source.cpp index 12bb4c729..2b6d9afa5 100644 --- a/src/mtconnect/source/loopback_source.cpp +++ b/src/mtconnect/source/loopback_source.cpp @@ -27,6 +27,7 @@ #include "mtconnect/pipeline/period_filter.hpp" #include "mtconnect/pipeline/timestamp_extractor.hpp" #include "mtconnect/pipeline/upcase_value.hpp" +#include "mtconnect/pipeline/validator.hpp" using namespace std; @@ -36,6 +37,8 @@ namespace mtconnect::source { using namespace pipeline; void LoopbackPipeline::build(const ConfigOptions &options) { + m_options = options; + clear(); TransformPtr next = m_start; @@ -56,6 +59,10 @@ namespace mtconnect::source { if (IsOptionSet(m_options, configuration::ConversionRequired)) next = next->bind(make_shared()); + // Validate Values + if (IsOptionSet(m_options, configuration::Validation)) + next = next->bind(make_shared(m_context)); + // Deliver next->bind(make_shared(m_context)); applySplices(); diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index 24af87c85..d0bb08abb 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,13 +1,25 @@ - Validation ControlledVocabularies { +const Validation ControlledVocabularies { + {"ACTIVE_AXES", {}}, {"ACTUATOR_STATE", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ALARM", {}}, + {"ASSET_CHANGED", {}}, + {"ASSET_REMOVED", {}}, {"AVAILABILITY", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, {"AXIS_COUPLING", {{"TANDEM", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}, {"SLAVE", 0}}}, + {"AXIS_FEEDRATE_OVERRIDE", {}}, {"AXIS_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, {"AXIS_STATE", {{"HOME", 0}, {"TRAVEL", 0}, {"PARKED", 0}, {"STOPPED", 0}}}, + {"BLOCK", {}}, + {"BLOCK_COUNT", {}}, {"CHUCK_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, {"CHUCK_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, + {"CODE", {}}, + {"COMPOSITION_STATE", {}}, {"CONTROLLER_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"EDIT", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, {"CONTROLLER_MODE_OVERRIDE", {{"ON", 0}, {"OFF", 0}}}, + {"COUPLED_AXES", {}}, + {"DATE_CODE", {}}, + {"DEVICE_UUID", {}}, {"DIRECTION", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, {"DOOR_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, {"EMERGENCY_STOP", {{"ARMED", 0}, {"TRIGGERED", 0}}}, @@ -15,25 +27,113 @@ {"EQUIPMENT_MODE", {{"ON", 0}, {"OFF", 0}}}, {"EXECUTION", {{"READY", 0}, {"ACTIVE", 0}, {"INTERRUPTED", 0}, {"FEED_HOLD", 0}, {"STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"PROGRAM_STOPPED", 0}, {"PROGRAM_COMPLETED", 0}, {"WAIT", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, {"FUNCTIONAL_MODE", {{"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}, {"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}}}, + {"HARDNESS", {}}, + {"LINE", {}}, + {"LINE_LABEL", {}}, + {"LINE_NUMBER", {}}, + {"MATERIAL", {}}, + {"MATERIAL_LAYER", {}}, + {"MESSAGE", {}}, + {"OPERATOR_ID", {}}, + {"PALLET_ID", {}}, + {"PART_COUNT", {}}, {"PART_DETECT", {{"PRESENT", 0}, {"NOT_PRESENT", 0}}}, + {"PART_ID", {}}, + {"PART_NUMBER", {}}, + {"PATH_FEEDRATE_OVERRIDE", {}}, {"PATH_MODE", {{"INDEPENDENT", 0}, {"MASTER", 0}, {"SYNCHRONOUS", 0}, {"MIRROR", 0}}}, {"POWER_STATE", {{"ON", 0}, {"OFF", 0}}}, {"POWER_STATUS", {{"ON", SCHEMA_VERSION(1, 1)}, {"OFF", SCHEMA_VERSION(1, 1)}}}, + {"PROCESS_TIME", {}}, + {"PROGRAM", {}}, + {"PROGRAM_COMMENT", {}}, {"PROGRAM_EDIT", {{"ACTIVE", 0}, {"READY", 0}, {"NOT_READY", 0}}}, + {"PROGRAM_EDIT_NAME", {}}, + {"PROGRAM_HEADER", {}}, + {"PROGRAM_LOCATION", {}}, {"PROGRAM_LOCATION_TYPE", {{"LOCAL", 0}, {"EXTERNAL", 0}}}, + {"PROGRAM_NEST_LEVEL", {}}, {"ROTARY_MODE", {{"SPINDLE", 0}, {"INDEX", 0}, {"CONTOUR", 0}}}, + {"ROTARY_VELOCITY_OVERRIDE", {}}, + {"SERIAL_NUMBER", {}}, {"SPINDLE_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"TOOL_ASSET_ID", {}}, + {"TOOL_GROUP", {}}, + {"TOOL_ID", {}}, + {"TOOL_NUMBER", {}}, + {"TOOL_OFFSET", {}}, + {"USER", {}}, + {"VARIABLE", {}}, {"WAIT_STATE", {{"POWERING_UP", 0}, {"POWERING_DOWN", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}, {"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"SECONDARY_PROCESS", 0}, {"PAUSING", 0}, {"RESUMING", 0}}}, + {"WIRE", {}}, + {"WORKHOLDING_ID", {}}, + {"WORK_OFFSET", {}}, + {"OPERATING_SYSTEM", {}}, + {"FIRMWARE", {}}, + {"APPLICATION", {}}, + {"LIBRARY", {}}, + {"HARDWARE", {}}, + {"NETWORK", {}}, + {"ROTATION", {}}, + {"TRANSLATION", {}}, + {"PROCESS_KIND_ID", {}}, {"PART_STATUS", {{"PASS", 0}, {"FAIL", 0}}}, + {"ALARM_LIMIT", {}}, + {"PROCESS_AGGREGATE_ID", {}}, + {"PART_KIND_ID", {}}, + {"ADAPTER_URI", {}}, + {"DEVICE_REMOVED", {}}, + {"DEVICE_CHANGED", {}}, + {"SPECIFICATION_LIMIT", {}}, {"CONNECTION_STATUS", {{"CLOSED", 0}, {"LISTEN", 0}, {"ESTABLISHED", 0}}}, + {"ADAPTER_SOFTWARE_VERSION", {}}, + {"SENSOR_ATTACHMENT", {}}, + {"CONTROL_LIMIT", {}}, + {"DEVICE_ADDED", {}}, + {"MTCONNECT_VERSION", {}}, + {"PROCESS_OCCURRENCE_ID", {}}, + {"PART_GROUP_ID", {}}, + {"PART_UNIQUE_ID", {}}, + {"ACTIVATION_COUNT", {}}, + {"DEACTIVATION_COUNT", {}}, + {"TRANSFER_COUNT", {}}, + {"LOAD_COUNT", {}}, {"PART_PROCESSING_STATE", {{"NEEDS_PROCESSING", 0}, {"IN_PROCESS", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"WAITING_FOR_TRANSIT", 0}, {"IN_TRANSIT", 0}, {"TRANSIT_COMPLETE", 0}}}, {"PROCESS_STATE", {{"INITIALIZING", 0}, {"READY", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INTERRUPTED", 0}, {"ABORTED", 0}}}, {"VALVE_STATE", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, {"LOCK_STATE", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, + {"UNLOAD_COUNT", {}}, + {"CYCLE_COUNT", {}}, {"OPERATING_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, + {"ASSET_COUNT", {}}, + {"MAINTENANCE_LIST", {}}, + {"FIXTURE_ID", {}}, {"PART_COUNT_TYPE", {{"EACH", 0}, {"BATCH", 0}}}, + {"CLOCK_TIME", {}}, + {"NETWORK_PORT", {}}, + {"HOST_NAME", {}}, {"LEAK_DETECT", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, {"BATTERY_STATE", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGING", 0}, {"DISCHARGED", 0}}}, + {"FEATURE_PERSISTENT_ID", {}}, + {"SENSOR_STATE", {}}, + {"COMPONENT_DATA", {}}, + {"WORK_OFFSETS", {}}, + {"TOOL_OFFSETS", {}}, + {"FEATURE_MEASUREMENT", {}}, + {"ADAPTER_URI", {}}, + {"MEASUREMENT_TYPE", {}}, + {"MEASUREMENT_VALUE", {}}, + {"MEASUREMENT_UNITS", {}}, {"ADAPTER_URI", {{"PASS", 0}, {"FAIL", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"UNDEFINED", 0}}}, - {"UNCERTAINTY_TYPE", {{"COMBINED", 0}, {"MEAN", 0}}} + {"UNCERTAINTY_TYPE", {{"COMBINED", 0}, {"MEAN", 0}}}, + {"UNCERTAINTY", {}}, + {"ALARM_LIMIT", {}}, + {"CONTROL_LIMIT", {}}, + {"SPECIFICATION_LIMIT", {}}, + {"TOOL_CUTTING_ITEM", {}}, + {"LOCATION_ADDRESS", {}}, + {"ACTIVE_POWER_SOURCE", {}}, + {"LOCATION_NARRATIVE", {}}, + {"THICKNESS", {}}, + {"LOCATION_SPATIAL_GEOGRAPHIC", {}} }; diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index f540d6131..a9d8c0055 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -25,5 +25,5 @@ namespace mtconnect::validation::observations { using Validation = std::unordered_map>; - extern Validation ControlledVocabularies; + const extern Validation ControlledVocabularies; } diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index 927946eb0..08a4e1ffd 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -277,6 +277,7 @@ add_agent_test(pipeline_edit FALSE pipeline) add_agent_test(mtconnect_xml_transform FALSE pipeline) add_agent_test(response_document FALSE pipeline) add_agent_test(json_mapping FALSE pipeline) +add_agent_test(observation_validation TRUE pipeline) add_agent_test(agent TRUE core) add_agent_test(globals FALSE core) diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp new file mode 100644 index 000000000..be6699ab0 --- /dev/null +++ b/test_package/observation_validation_test.cpp @@ -0,0 +1,143 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Ensure that gtest is the first header otherwise Windows raises an error +#include +// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) + +#include + +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/observation/observation.hpp" +#include "mtconnect/pipeline/validator.hpp" +#include "mtconnect/asset/asset.hpp" +#include "mtconnect/device_model/data_item/data_item.hpp" + +using namespace mtconnect; +using namespace mtconnect::pipeline; +using namespace mtconnect::observation; +using namespace mtconnect::asset; +using namespace mtconnect::device_model::data_item; +using namespace std; +using namespace date::literals; +using namespace std::literals; + +// main +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +class MockPipelineContract : public PipelineContract +{ +public: + MockPipelineContract(std::map &items, int32_t schemaVersion) + : m_dataItems(items), m_schemaVersion(schemaVersion) + {} + DevicePtr findDevice(const std::string &) override { return nullptr; } + DataItemPtr findDataItem(const std::string &device, const std::string &name) override + { + return m_dataItems[name]; + } + void eachDataItem(EachDataItem fun) override {} + void deliverObservation(observation::ObservationPtr obs) override {} + void deliverAsset(AssetPtr) override {} + void deliverDevices(std::list) override {} + int32_t getSchemaVersion() const override { return m_schemaVersion; } + void deliverAssetCommand(entity::EntityPtr) override {} + void deliverCommand(entity::EntityPtr) override {} + void deliverConnectStatus(entity::EntityPtr, const StringList &, bool) override {} + void sourceFailed(const std::string &id) override {} + const ObservationPtr checkDuplicate(const ObservationPtr &obs) const override { return obs; } + + std::map &m_dataItems; + int32_t m_schemaVersion; +}; + +class ObservationValidationTest : public testing::Test +{ +protected: + void SetUp() override + { + m_context = make_shared(); + m_validator = make_shared(m_context); + m_validator->bind(make_shared(TypeGuard(RUN))); + m_time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; + + ErrorList errors; + m_dataItem = DataItem::make( + {{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, + errors); + } + + void TearDown() override + { + m_validator.reset(); + m_dataItem.reset(); + m_context.reset(); + } + + shared_ptr m_validator; + shared_ptr m_context; + DataItemPtr m_dataItem; + Timestamp m_time; +}; + +TEST_F(ObservationValidationTest, should_validate_value) +{ + ErrorList errors; + auto event = Observation::make(m_dataItem, {{"VALUE", "READY"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); +} + +TEST_F(ObservationValidationTest, unavailable_should_be_valid) +{ + ErrorList errors; + auto event = Observation::make(m_dataItem, {{"VALUE", "UNAVAILABLE"s}}, m_time, errors); + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); +} + +TEST_F(ObservationValidationTest, should_detect_invalid_value) +{ + ErrorList errors; + auto event = Observation::make(m_dataItem, {{"VALUE", "FLABOR"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("INVALID", quality); +} + +TEST_F(ObservationValidationTest, should_not_validate_unknown_type) +{ + ErrorList errors; + m_dataItem = DataItem::make( + {{"id", "exec"s}, {"category", "EVENT"s}, {"type", "x:FLABOR"s}}, + errors); + + auto event = Observation::make(m_dataItem, {{"VALUE", "FLABOR"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("UNVERIFIABLE", quality); +} + From 06434b4f214481248446a9e12c1034a66e88aa43 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 5 Apr 2024 23:40:31 -0400 Subject: [PATCH 066/128] added log once logic --- src/mtconnect/pipeline/validator.hpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index 995200c94..3524d03de 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -73,7 +73,17 @@ namespace mtconnect::pipeline { { evt->setProperty("quality", std::string("INVALID")); // Log once - LOG(warning) << "Invalid value for '" << type << "' " << evt->getValue(); + auto &id = di->getId(); + if (m_logOnce.count(id) < 1) + { + LOG(warning) << id << ": Invalid value for '" << type << "' " << evt->getValue(); + m_logOnce.insert(id); + } + else + { + LOG(trace) << id << ": Invalid value for '" << type << "' " << evt->getValue(); + + } } } else From 5b07ed14b53af996b5d905f5f9e312ad5b5d08ae Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 13:54:11 -0400 Subject: [PATCH 067/128] Added validation header tests --- src/mtconnect/pipeline/validator.hpp | 9 +- .../validation/observation_validations.hpp | 276 +++++++++--------- src/mtconnect/validation/observations.hpp | 2 +- test_package/agent_test.cpp | 73 ++++- 4 files changed, 211 insertions(+), 149 deletions(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index 3524d03de..ef2d74366 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -47,17 +47,16 @@ namespace mtconnect::pipeline { auto evt = std::dynamic_pointer_cast(entity); auto di = evt->getDataItem(); - auto &type = di->getType(); auto &value = evt->getValue(); - if (value == "UNAVAILABLE") + if (evt->isUnavailable()) { evt->setProperty("quality", std::string("VALID")); } else { // Optimize - auto vocab = ControlledVocabularies.find(type); + auto vocab = ControlledVocabularies.find(evt->getName()); if (vocab != ControlledVocabularies.end()) { auto &lits = vocab->second; @@ -76,12 +75,12 @@ namespace mtconnect::pipeline { auto &id = di->getId(); if (m_logOnce.count(id) < 1) { - LOG(warning) << id << ": Invalid value for '" << type << "' " << evt->getValue(); + LOG(warning) << "DataItem '" << id << "': Invalid value for '" << evt->getName() << "': '" << evt->getValue() << '\''; m_logOnce.insert(id); } else { - LOG(trace) << id << ": Invalid value for '" << type << "' " << evt->getValue(); + LOG(trace) << "DataItem '" << id << "': Invalid value for '" << evt->getName() << "': '" << evt->getValue() << '\''; } } diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index d0bb08abb..b4bb92f18 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,139 +1,139 @@ -const Validation ControlledVocabularies { - {"ACTIVE_AXES", {}}, - {"ACTUATOR_STATE", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"ALARM", {}}, - {"ASSET_CHANGED", {}}, - {"ASSET_REMOVED", {}}, - {"AVAILABILITY", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, - {"AXIS_COUPLING", {{"TANDEM", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}, {"SLAVE", 0}}}, - {"AXIS_FEEDRATE_OVERRIDE", {}}, - {"AXIS_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"AXIS_STATE", {{"HOME", 0}, {"TRAVEL", 0}, {"PARKED", 0}, {"STOPPED", 0}}}, - {"BLOCK", {}}, - {"BLOCK_COUNT", {}}, - {"CHUCK_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"CHUCK_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, - {"CODE", {}}, - {"COMPOSITION_STATE", {}}, - {"CONTROLLER_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"EDIT", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, - {"CONTROLLER_MODE_OVERRIDE", {{"ON", 0}, {"OFF", 0}}}, - {"COUPLED_AXES", {}}, - {"DATE_CODE", {}}, - {"DEVICE_UUID", {}}, - {"DIRECTION", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, - {"DOOR_STATE", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, - {"EMERGENCY_STOP", {{"ARMED", 0}, {"TRIGGERED", 0}}}, - {"END_OF_BAR", {{"YES", 0}, {"NO", 0}}}, - {"EQUIPMENT_MODE", {{"ON", 0}, {"OFF", 0}}}, - {"EXECUTION", {{"READY", 0}, {"ACTIVE", 0}, {"INTERRUPTED", 0}, {"FEED_HOLD", 0}, {"STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"PROGRAM_STOPPED", 0}, {"PROGRAM_COMPLETED", 0}, {"WAIT", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, - {"FUNCTIONAL_MODE", {{"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}, {"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}}}, - {"HARDNESS", {}}, - {"LINE", {}}, - {"LINE_LABEL", {}}, - {"LINE_NUMBER", {}}, - {"MATERIAL", {}}, - {"MATERIAL_LAYER", {}}, - {"MESSAGE", {}}, - {"OPERATOR_ID", {}}, - {"PALLET_ID", {}}, - {"PART_COUNT", {}}, - {"PART_DETECT", {{"PRESENT", 0}, {"NOT_PRESENT", 0}}}, - {"PART_ID", {}}, - {"PART_NUMBER", {}}, - {"PATH_FEEDRATE_OVERRIDE", {}}, - {"PATH_MODE", {{"INDEPENDENT", 0}, {"MASTER", 0}, {"SYNCHRONOUS", 0}, {"MIRROR", 0}}}, - {"POWER_STATE", {{"ON", 0}, {"OFF", 0}}}, - {"POWER_STATUS", {{"ON", SCHEMA_VERSION(1, 1)}, {"OFF", SCHEMA_VERSION(1, 1)}}}, - {"PROCESS_TIME", {}}, - {"PROGRAM", {}}, - {"PROGRAM_COMMENT", {}}, - {"PROGRAM_EDIT", {{"ACTIVE", 0}, {"READY", 0}, {"NOT_READY", 0}}}, - {"PROGRAM_EDIT_NAME", {}}, - {"PROGRAM_HEADER", {}}, - {"PROGRAM_LOCATION", {}}, - {"PROGRAM_LOCATION_TYPE", {{"LOCAL", 0}, {"EXTERNAL", 0}}}, - {"PROGRAM_NEST_LEVEL", {}}, - {"ROTARY_MODE", {{"SPINDLE", 0}, {"INDEX", 0}, {"CONTOUR", 0}}}, - {"ROTARY_VELOCITY_OVERRIDE", {}}, - {"SERIAL_NUMBER", {}}, - {"SPINDLE_INTERLOCK", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"TOOL_ASSET_ID", {}}, - {"TOOL_GROUP", {}}, - {"TOOL_ID", {}}, - {"TOOL_NUMBER", {}}, - {"TOOL_OFFSET", {}}, - {"USER", {}}, - {"VARIABLE", {}}, - {"WAIT_STATE", {{"POWERING_UP", 0}, {"POWERING_DOWN", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}, {"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"SECONDARY_PROCESS", 0}, {"PAUSING", 0}, {"RESUMING", 0}}}, - {"WIRE", {}}, - {"WORKHOLDING_ID", {}}, - {"WORK_OFFSET", {}}, - {"OPERATING_SYSTEM", {}}, - {"FIRMWARE", {}}, - {"APPLICATION", {}}, - {"LIBRARY", {}}, - {"HARDWARE", {}}, - {"NETWORK", {}}, - {"ROTATION", {}}, - {"TRANSLATION", {}}, - {"PROCESS_KIND_ID", {}}, - {"PART_STATUS", {{"PASS", 0}, {"FAIL", 0}}}, - {"ALARM_LIMIT", {}}, - {"PROCESS_AGGREGATE_ID", {}}, - {"PART_KIND_ID", {}}, - {"ADAPTER_URI", {}}, - {"DEVICE_REMOVED", {}}, - {"DEVICE_CHANGED", {}}, - {"SPECIFICATION_LIMIT", {}}, - {"CONNECTION_STATUS", {{"CLOSED", 0}, {"LISTEN", 0}, {"ESTABLISHED", 0}}}, - {"ADAPTER_SOFTWARE_VERSION", {}}, - {"SENSOR_ATTACHMENT", {}}, - {"CONTROL_LIMIT", {}}, - {"DEVICE_ADDED", {}}, - {"MTCONNECT_VERSION", {}}, - {"PROCESS_OCCURRENCE_ID", {}}, - {"PART_GROUP_ID", {}}, - {"PART_UNIQUE_ID", {}}, - {"ACTIVATION_COUNT", {}}, - {"DEACTIVATION_COUNT", {}}, - {"TRANSFER_COUNT", {}}, - {"LOAD_COUNT", {}}, - {"PART_PROCESSING_STATE", {{"NEEDS_PROCESSING", 0}, {"IN_PROCESS", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"WAITING_FOR_TRANSIT", 0}, {"IN_TRANSIT", 0}, {"TRANSIT_COMPLETE", 0}}}, - {"PROCESS_STATE", {{"INITIALIZING", 0}, {"READY", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INTERRUPTED", 0}, {"ABORTED", 0}}}, - {"VALVE_STATE", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, - {"LOCK_STATE", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, - {"UNLOAD_COUNT", {}}, - {"CYCLE_COUNT", {}}, - {"OPERATING_MODE", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, - {"ASSET_COUNT", {}}, - {"MAINTENANCE_LIST", {}}, - {"FIXTURE_ID", {}}, - {"PART_COUNT_TYPE", {{"EACH", 0}, {"BATCH", 0}}}, - {"CLOCK_TIME", {}}, - {"NETWORK_PORT", {}}, - {"HOST_NAME", {}}, - {"LEAK_DETECT", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, - {"BATTERY_STATE", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGING", 0}, {"DISCHARGED", 0}}}, - {"FEATURE_PERSISTENT_ID", {}}, - {"SENSOR_STATE", {}}, - {"COMPONENT_DATA", {}}, - {"WORK_OFFSETS", {}}, - {"TOOL_OFFSETS", {}}, - {"FEATURE_MEASUREMENT", {}}, - {"ADAPTER_URI", {}}, - {"MEASUREMENT_TYPE", {}}, - {"MEASUREMENT_VALUE", {}}, - {"MEASUREMENT_UNITS", {}}, - {"ADAPTER_URI", {{"PASS", 0}, {"FAIL", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"UNDEFINED", 0}}}, - {"UNCERTAINTY_TYPE", {{"COMBINED", 0}, {"MEAN", 0}}}, - {"UNCERTAINTY", {}}, - {"ALARM_LIMIT", {}}, - {"CONTROL_LIMIT", {}}, - {"SPECIFICATION_LIMIT", {}}, - {"TOOL_CUTTING_ITEM", {}}, - {"LOCATION_ADDRESS", {}}, - {"ACTIVE_POWER_SOURCE", {}}, - {"LOCATION_NARRATIVE", {}}, - {"THICKNESS", {}}, - {"LOCATION_SPATIAL_GEOGRAPHIC", {}} + Validation ControlledVocabularies { + {"ActiveAxes", {}}, + {"ActuatorState", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"Alarm", {}}, + {"AssetChanged", {}}, + {"AssetRemoved", {}}, + {"Availability", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, + {"AxisCoupling", {{"TANDEM", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}, {"SLAVE", 0}}}, + {"AxisFeedrateOverride", {}}, + {"AxisInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"AxisState", {{"HOME", 0}, {"TRAVEL", 0}, {"PARKED", 0}, {"STOPPED", 0}}}, + {"Block", {}}, + {"BlockCount", {}}, + {"ChuckInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ChuckState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, + {"Code", {}}, + {"CompositionState", {}}, + {"ControllerMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"EDIT", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, + {"ControllerModeOverride", {{"ON", 0}, {"OFF", 0}}}, + {"CoupledAxes", {}}, + {"DateCode", {}}, + {"DeviceUuid", {}}, + {"Direction", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, + {"DoorState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, + {"EmergencyStop", {{"ARMED", 0}, {"TRIGGERED", 0}}}, + {"EndOfBar", {{"YES", 0}, {"NO", 0}}}, + {"EquipmentMode", {{"ON", 0}, {"OFF", 0}}}, + {"Execution", {{"READY", 0}, {"ACTIVE", 0}, {"INTERRUPTED", 0}, {"FEED_HOLD", 0}, {"STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"PROGRAM_STOPPED", 0}, {"PROGRAM_COMPLETED", 0}, {"WAIT", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, + {"FunctionalMode", {{"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}, {"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}}}, + {"Hardness", {}}, + {"Line", {}}, + {"LineLabel", {}}, + {"LineNumber", {}}, + {"Material", {}}, + {"MaterialLayer", {}}, + {"Message", {}}, + {"OperatorId", {}}, + {"PalletId", {}}, + {"PartCount", {}}, + {"PartDetect", {{"PRESENT", 0}, {"NOT_PRESENT", 0}}}, + {"PartId", {}}, + {"PartNumber", {}}, + {"PathFeedrateOverride", {}}, + {"PathMode", {{"INDEPENDENT", 0}, {"MASTER", 0}, {"SYNCHRONOUS", 0}, {"MIRROR", 0}}}, + {"PowerState", {{"ON", 0}, {"OFF", 0}}}, + {"PowerStatus", {{"ON", SCHEMA_VERSION(1, 1)}, {"OFF", SCHEMA_VERSION(1, 1)}}}, + {"ProcessTime", {}}, + {"Program", {}}, + {"ProgramComment", {}}, + {"ProgramEdit", {{"ACTIVE", 0}, {"READY", 0}, {"NOT_READY", 0}}}, + {"ProgramEditName", {}}, + {"ProgramHeader", {}}, + {"ProgramLocation", {}}, + {"ProgramLocationType", {{"LOCAL", 0}, {"EXTERNAL", 0}}}, + {"ProgramNestLevel", {}}, + {"RotaryMode", {{"SPINDLE", 0}, {"INDEX", 0}, {"CONTOUR", 0}}}, + {"RotaryVelocityOverride", {}}, + {"SerialNumber", {}}, + {"SpindleInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ToolAssetId", {}}, + {"ToolGroup", {}}, + {"ToolId", {}}, + {"ToolNumber", {}}, + {"ToolOffset", {}}, + {"User", {}}, + {"Variable", {}}, + {"WaitState", {{"POWERING_UP", 0}, {"POWERING_DOWN", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}, {"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"SECONDARY_PROCESS", 0}, {"PAUSING", 0}, {"RESUMING", 0}}}, + {"Wire", {}}, + {"WorkholdingId", {}}, + {"WorkOffset", {}}, + {"OperatingSystem", {}}, + {"Firmware", {}}, + {"Application", {}}, + {"Library", {}}, + {"Hardware", {}}, + {"Network", {}}, + {"Rotation", {}}, + {"Translation", {}}, + {"ProcessKindId", {}}, + {"PartStatus", {{"PASS", 0}, {"FAIL", 0}}}, + {"AlarmLimit", {}}, + {"ProcessAggregateId", {}}, + {"PartKindId", {}}, + {"AdapterURI", {}}, + {"DeviceRemoved", {}}, + {"DeviceChanged", {}}, + {"SpecificationLimit", {}}, + {"ConnectionStatus", {{"CLOSED", 0}, {"LISTEN", 0}, {"ESTABLISHED", 0}}}, + {"AdapterSoftwareVersion", {}}, + {"SensorAttachment", {}}, + {"ControlLimit", {}}, + {"DeviceAdded", {}}, + {"MTConnectVersion", {}}, + {"ProcessOccurrenceId", {}}, + {"PartGroupId", {}}, + {"PartUniqueId", {}}, + {"ActivationCount", {}}, + {"DeactivationCount", {}}, + {"TransferCount", {}}, + {"LoadCount", {}}, + {"PartProcessingState", {{"NEEDS_PROCESSING", 0}, {"IN_PROCESS", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"WAITING_FOR_TRANSIT", 0}, {"IN_TRANSIT", 0}, {"TRANSIT_COMPLETE", 0}}}, + {"ProcessState", {{"INITIALIZING", 0}, {"READY", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INTERRUPTED", 0}, {"ABORTED", 0}}}, + {"ValveState", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, + {"LockState", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, + {"UnloadCount", {}}, + {"CycleCount", {}}, + {"OperatingMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, + {"AssetCount", {}}, + {"MaintenanceList", {}}, + {"FixtureId", {}}, + {"PartCountType", {{"EACH", 0}, {"BATCH", 0}}}, + {"ClockTime", {}}, + {"NetworkPort", {}}, + {"HostName", {}}, + {"LeakDetect", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, + {"BatteryState", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGING", 0}, {"DISCHARGED", 0}}}, + {"FeaturePersisitentId", {}}, + {"SensorState", {}}, + {"ComponentData", {}}, + {"WorkOffsets", {}}, + {"ToolOffsets", {}}, + {"FeatureMeasurement", {}}, + {"CharacteristicPersistentId", {}}, + {"MeasurementType", {}}, + {"MeasurementValue", {}}, + {"MeasurementUnits", {}}, + {"CharacteristicStatus", {{"PASS", 0}, {"FAIL", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"UNDEFINED", 0}}}, + {"UncertaintyType", {{"COMBINED", 0}, {"MEAN", 0}}}, + {"Uncertainty", {}}, + {"AlarmLimits", {}}, + {"ControlLimits", {}}, + {"SpecificationLimits", {}}, + {"ToolCuttingItem", {}}, + {"LocationAddress", {}}, + {"ActivePowerSource", {}}, + {"LocationNarrative", {}}, + {"Thickness", {}}, + {"LocationSpatialGeographic", {}} }; diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index a9d8c0055..f540d6131 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -25,5 +25,5 @@ namespace mtconnect::validation::observations { using Validation = std::unordered_map>; - const extern Validation ControlledVocabularies; + extern Validation ControlledVocabularies; } diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 0021a7718..02c2752a2 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -548,7 +548,7 @@ TEST_F(AgentTest, SampleAtNextSeq) } } -TEST_F(AgentTest, SampleCount) +TEST_F(AgentTest, should_give_correct_number_of_samples_with_count) { QueryMap query; addAdapter(); @@ -584,7 +584,7 @@ TEST_F(AgentTest, SampleCount) } } -TEST_F(AgentTest, SampleLastCount) +TEST_F(AgentTest, should_give_correct_number_of_samples_with_negative_count) { QueryMap query; addAdapter(); @@ -620,7 +620,7 @@ TEST_F(AgentTest, SampleLastCount) } } -TEST_F(AgentTest, SampleToParameter) +TEST_F(AgentTest, should_give_correct_number_of_samples_with_to_parameter) { QueryMap query; addAdapter(); @@ -683,7 +683,7 @@ TEST_F(AgentTest, SampleToParameter) // to > from } -TEST_F(AgentTest, EmptyStream) +TEST_F(AgentTest, should_give_empty_stream_with_no_new_samples) { { PARSE_XML_RESPONSE("/current"); @@ -741,7 +741,7 @@ TEST_F(AgentTest, AddToBuffer) } } -TEST_F(AgentTest, SequenceNumberRollover) +TEST_F(AgentTest, should_int_64_sequences_should_not_truncate_at_32_bits) { #ifndef WIN32 QueryMap query; @@ -3110,3 +3110,66 @@ TEST_F(AgentTest, should_initialize_observaton_to_initial_value_when_available) ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:PartCount", "0"); } } + +TEST_F(AgentTest, should_set_validation_flag_in_header_when_version_2_5_validation_on) +{ + auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.5", 4, false, + true, {{configuration::Validation, true}}); + ASSERT_TRUE(agent); + { + PARSE_XML_RESPONSE("/probe"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); + } + + { + PARSE_XML_RESPONSE("/current"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); + } + + { + PARSE_XML_RESPONSE("/sample"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); + } +} + +TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_version_below_2_5) +{ + auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.4", 4, false, + true, {{configuration::Validation, true}}); + ASSERT_TRUE(agent); + { + PARSE_XML_RESPONSE("/probe"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } + + { + PARSE_XML_RESPONSE("/current"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } + + { + PARSE_XML_RESPONSE("/sample"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } +} + +TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_false) +{ + auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.5", 4, false, + true, {{configuration::Validation, false}}); + ASSERT_TRUE(agent); + { + PARSE_XML_RESPONSE("/probe"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } + + { + PARSE_XML_RESPONSE("/current"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } + + { + PARSE_XML_RESPONSE("/sample"); + ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); + } +} From 0adfe7418c753d584ce611f23ca18c4f6f69bdb1 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 13:54:11 -0400 Subject: [PATCH 068/128] Added validation header tests --- src/mtconnect/agent.cpp | 9 +- src/mtconnect/pipeline/validator.hpp | 19 ++--- src/mtconnect/printer/json_printer.cpp | 22 ++--- src/mtconnect/printer/printer.hpp | 13 +-- src/mtconnect/printer/xml_printer.cpp | 7 +- .../source/adapter/adapter_pipeline.cpp | 2 +- src/mtconnect/source/loopback_source.cpp | 2 +- .../validation/observation_validations.hpp | 83 ++++++++++++++++--- src/mtconnect/validation/observations.hpp | 9 +- test_package/agent_test.cpp | 12 +++ test_package/observation_validation_test.cpp | 27 +++--- 11 files changed, 136 insertions(+), 69 deletions(-) diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index 272c23471..9340c3d18 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -58,9 +58,8 @@ #include "mtconnect/sink/rest_sink/file_cache.hpp" #include "mtconnect/sink/rest_sink/session.hpp" #include "mtconnect/utilities.hpp" -#include "mtconnect/version.h" - #include "mtconnect/validation/observations.hpp" +#include "mtconnect/version.h" using namespace std; @@ -173,13 +172,14 @@ namespace mtconnect { if (!m_observationsInitialized) { - if (m_intSchemaVersion < SCHEMA_VERSION(2, 5) && IsOptionSet(m_options, mtconnect::configuration::Validation)) + if (m_intSchemaVersion < SCHEMA_VERSION(2, 5) && + IsOptionSet(m_options, mtconnect::configuration::Validation)) { m_validation = false; for (auto &printer : m_printers) printer.second->setValidation(false); } - + for (auto device : m_deviceIndex) initializeDataItems(device); @@ -203,7 +203,6 @@ namespace mtconnect { } m_observationsInitialized = true; - } } diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index ef2d74366..b99b72565 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -27,28 +27,26 @@ namespace mtconnect::pipeline { using namespace entity; - + /// @brief Map a token list to data items or asset types class AGENT_LIB_API Validator : public Transform { public: Validator(const Validator &) = default; Validator(PipelineContextPtr context) - : Transform("Validator"), - m_contract(context->m_contract.get()) + : Transform("Validator"), m_contract(context->m_contract.get()) { m_guard = TypeGuard(RUN) || TypeGuard(SKIP); } - + EntityPtr operator()(entity::EntityPtr &&entity) override { using namespace observation; using namespace mtconnect::validation::observations; auto evt = std::dynamic_pointer_cast(entity); - + auto di = evt->getDataItem(); auto &value = evt->getValue(); - if (evt->isUnavailable()) { evt->setProperty("quality", std::string("VALID")); @@ -75,13 +73,14 @@ namespace mtconnect::pipeline { auto &id = di->getId(); if (m_logOnce.count(id) < 1) { - LOG(warning) << "DataItem '" << id << "': Invalid value for '" << evt->getName() << "': '" << evt->getValue() << '\''; + LOG(warning) << "DataItem '" << id << "': Invalid value for '" << evt->getName() + << "': '" << evt->getValue() << '\''; m_logOnce.insert(id); } else { - LOG(trace) << "DataItem '" << id << "': Invalid value for '" << evt->getName() << "': '" << evt->getValue() << '\''; - + LOG(trace) << "DataItem '" << id << "': Invalid value for '" << evt->getName() + << "': '" << evt->getValue() << '\''; } } } @@ -95,7 +94,7 @@ namespace mtconnect::pipeline { evt->setProperty("quality", std::string("UNVERIFIABLE")); } } - + return next(std::move(evt)); } diff --git a/src/mtconnect/printer/json_printer.cpp b/src/mtconnect/printer/json_printer.cpp index 2720d5eaa..287203797 100644 --- a/src/mtconnect/printer/json_printer.cpp +++ b/src/mtconnect/printer/json_printer.cpp @@ -60,8 +60,7 @@ namespace mtconnect::printer { template inline void header(AutoJsonObject &obj, const string &version, const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, - const string &schemaVersion, const string modelChangeTime, - bool validation) + const string &schemaVersion, const string modelChangeTime, bool validation) { obj.AddPairs("version", version, "creationTime", getCurrentTime(GMT), "testIndicator", false, "instanceId", instanceId, "sender", hostname, "schemaVersion", schemaVersion); @@ -72,7 +71,6 @@ namespace mtconnect::printer { obj.AddPairs("bufferSize", bufferSize); if (validation) obj.AddPairs("validation", true); - } template @@ -80,10 +78,10 @@ namespace mtconnect::printer { const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetBufferSize, const unsigned int assetCount, const string &schemaVersion, - const string modelChangeTime, - const bool validation) + const string modelChangeTime, const bool validation) { - header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, validation); + header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, + validation); obj.AddPairs("assetBufferSize", assetBufferSize, "assetCount", assetCount); } @@ -92,10 +90,10 @@ namespace mtconnect::printer { const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSequence, const uint64_t firstSequence, const uint64_t lastSequence, const string &schemaVersion, - const string modelChangeTime, - const bool validation) + const string modelChangeTime, const bool validation) { - header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, validation); + header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, + validation); obj.AddPairs("nextSequence", nextSequence, "lastSequence", lastSequence, "firstSequence", firstSequence); } @@ -213,8 +211,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); probeAssetHeader(obj, m_version, m_senderName, instanceId, 0, bufferSize, assetCount, - *m_schemaVersion, m_modelChangeTime, - m_validation); + *m_schemaVersion, m_modelChangeTime, m_validation); } { obj.Key("Assets"); @@ -412,8 +409,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); streamHeader(obj, m_version, m_senderName, instanceId, bufferSize, nextSeq, firstSeq, - lastSeq, *m_schemaVersion, m_modelChangeTime, - m_validation); + lastSeq, *m_schemaVersion, m_modelChangeTime, m_validation); } { diff --git a/src/mtconnect/printer/printer.hpp b/src/mtconnect/printer/printer.hpp index 4e39cb0a8..52943c175 100644 --- a/src/mtconnect/printer/printer.hpp +++ b/src/mtconnect/printer/printer.hpp @@ -49,7 +49,9 @@ namespace mtconnect { public: /// @brief construct a printer /// @param pretty `true` if content should be pretty printed - Printer(bool pretty = false, bool validation = false) : m_pretty(pretty), m_validation(validation) {} + Printer(bool pretty = false, bool validation = false) + : m_pretty(pretty), m_validation(validation) + {} virtual ~Printer() = default; /// @brief Generate an MTConnect Error document @@ -145,19 +147,18 @@ namespace mtconnect { const_cast(this)->m_schemaVersion.emplace(ver); } } - + /// @brief Get validation header flag state /// @returns validation state bool getValidation() const { return m_validation; } - + /// @brief sets validation state /// @param validation the validation state void setValidation(bool v) { m_validation = v; } - protected: - bool m_pretty; //< Turns pretty printing on - bool m_validation; //< Sets validation flag in header + bool m_pretty; //< Turns pretty printing on + bool m_validation; //< Sets validation flag in header std::string m_modelChangeTime; std::optional m_schemaVersion; std::string m_senderName {"localhost"}; diff --git a/src/mtconnect/printer/xml_printer.cpp b/src/mtconnect/printer/xml_printer.cpp index f5b6ef574..1c155e98b 100644 --- a/src/mtconnect/printer/xml_printer.cpp +++ b/src/mtconnect/printer/xml_printer.cpp @@ -100,7 +100,10 @@ namespace mtconnect::printer { xmlBufferPtr m_buf; }; - XmlPrinter::XmlPrinter(bool pretty, bool validation) : Printer(pretty, validation) { NAMED_SCOPE("xml.printer"); } + XmlPrinter::XmlPrinter(bool pretty, bool validation) : Printer(pretty, validation) + { + NAMED_SCOPE("xml.printer"); + } void XmlPrinter::addDevicesNamespace(const std::string &urn, const std::string &location, const std::string &prefix) @@ -660,7 +663,7 @@ namespace mtconnect::printer { addAttribute(writer, "sender", m_senderName); addAttribute(writer, "instanceId", to_string(instanceId)); - + if (m_validation) addAttribute(writer, "validation", "true"s); diff --git a/src/mtconnect/source/adapter/adapter_pipeline.cpp b/src/mtconnect/source/adapter/adapter_pipeline.cpp index 615b47412..6432a6cfc 100644 --- a/src/mtconnect/source/adapter/adapter_pipeline.cpp +++ b/src/mtconnect/source/adapter/adapter_pipeline.cpp @@ -139,7 +139,7 @@ namespace mtconnect { // Convert values if (IsOptionSet(m_options, configuration::ConversionRequired)) next = next->bind(make_shared()); - + // Validate Values if (IsOptionSet(m_options, configuration::Validation)) next = next->bind(make_shared(m_context)); diff --git a/src/mtconnect/source/loopback_source.cpp b/src/mtconnect/source/loopback_source.cpp index 2b6d9afa5..1f21a70eb 100644 --- a/src/mtconnect/source/loopback_source.cpp +++ b/src/mtconnect/source/loopback_source.cpp @@ -38,7 +38,7 @@ namespace mtconnect::source { void LoopbackPipeline::build(const ConfigOptions &options) { m_options = options; - + clear(); TransformPtr next = m_start; diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index b4bb92f18..1f7cb73ef 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,4 +1,4 @@ - Validation ControlledVocabularies { +Validation ControlledVocabularies { {"ActiveAxes", {}}, {"ActuatorState", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, {"Alarm", {}}, @@ -15,18 +15,43 @@ {"ChuckState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, {"Code", {}}, {"CompositionState", {}}, - {"ControllerMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"EDIT", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, + {"ControllerMode", + {{"AUTOMATIC", 0}, + {"MANUAL", 0}, + {"MANUAL_DATA_INPUT", 0}, + {"SEMI_AUTOMATIC", 0}, + {"EDIT", 0}, + {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, {"ControllerModeOverride", {{"ON", 0}, {"OFF", 0}}}, {"CoupledAxes", {}}, {"DateCode", {}}, {"DeviceUuid", {}}, - {"Direction", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, + {"Direction", + {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, + {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, + {"POSITIVE", SCHEMA_VERSION(1, 4)}, + {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, {"DoorState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, {"EmergencyStop", {{"ARMED", 0}, {"TRIGGERED", 0}}}, {"EndOfBar", {{"YES", 0}, {"NO", 0}}}, {"EquipmentMode", {{"ON", 0}, {"OFF", 0}}}, - {"Execution", {{"READY", 0}, {"ACTIVE", 0}, {"INTERRUPTED", 0}, {"FEED_HOLD", 0}, {"STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"PROGRAM_STOPPED", 0}, {"PROGRAM_COMPLETED", 0}, {"WAIT", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, - {"FunctionalMode", {{"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}, {"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}}}, + {"Execution", + {{"READY", 0}, + {"ACTIVE", 0}, + {"INTERRUPTED", 0}, + {"FEED_HOLD", 0}, + {"STOPPED", 0}, + {"OPTIONAL_STOP", 0}, + {"PROGRAM_STOPPED", 0}, + {"PROGRAM_COMPLETED", 0}, + {"WAIT", 0}, + {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, + {"FunctionalMode", + {{"PRODUCTION", 0}, + {"SETUP", 0}, + {"TEARDOWN", 0}, + {"MAINTENANCE", 0}, + {"PROCESS_DEVELOPMENT", 0}}}, {"Hardness", {}}, {"Line", {}}, {"LineLabel", {}}, @@ -64,7 +89,18 @@ {"ToolOffset", {}}, {"User", {}}, {"Variable", {}}, - {"WaitState", {{"POWERING_UP", 0}, {"POWERING_DOWN", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}, {"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"SECONDARY_PROCESS", 0}, {"PAUSING", 0}, {"RESUMING", 0}}}, + {"WaitState", + {{"POWERING_UP", 0}, + {"POWERING_DOWN", 0}, + {"PART_LOAD", 0}, + {"PART_UNLOAD", 0}, + {"TOOL_LOAD", 0}, + {"TOOL_UNLOAD", 0}, + {"MATERIAL_LOAD", 0}, + {"MATERIAL_UNLOAD", 0}, + {"SECONDARY_PROCESS", 0}, + {"PAUSING", 0}, + {"RESUMING", 0}}}, {"Wire", {}}, {"WorkholdingId", {}}, {"WorkOffset", {}}, @@ -98,8 +134,26 @@ {"DeactivationCount", {}}, {"TransferCount", {}}, {"LoadCount", {}}, - {"PartProcessingState", {{"NEEDS_PROCESSING", 0}, {"IN_PROCESS", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"WAITING_FOR_TRANSIT", 0}, {"IN_TRANSIT", 0}, {"TRANSIT_COMPLETE", 0}}}, - {"ProcessState", {{"INITIALIZING", 0}, {"READY", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INTERRUPTED", 0}, {"ABORTED", 0}}}, + {"PartProcessingState", + {{"NEEDS_PROCESSING", 0}, + {"IN_PROCESS", 0}, + {"PROCESSING_ENDED", 0}, + {"PROCESSING_ENDED_COMPLETE", 0}, + {"PROCESSING_ENDED_STOPPED", 0}, + {"PROCESSING_ENDED_ABORTED", 0}, + {"PROCESSING_ENDED_LOST", 0}, + {"PROCESSING_ENDED_SKIPPED", 0}, + {"PROCESSING_ENDED_REJECTED", 0}, + {"WAITING_FOR_TRANSIT", 0}, + {"IN_TRANSIT", 0}, + {"TRANSIT_COMPLETE", 0}}}, + {"ProcessState", + {{"INITIALIZING", 0}, + {"READY", 0}, + {"ACTIVE", 0}, + {"COMPLETE", 0}, + {"INTERRUPTED", 0}, + {"ABORTED", 0}}}, {"ValveState", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, {"LockState", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, {"UnloadCount", {}}, @@ -124,7 +178,15 @@ {"MeasurementType", {}}, {"MeasurementValue", {}}, {"MeasurementUnits", {}}, - {"CharacteristicStatus", {{"PASS", 0}, {"FAIL", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"UNDEFINED", 0}}}, + {"CharacteristicStatus", + {{"PASS", 0}, + {"FAIL", 0}, + {"REWORK", 0}, + {"SYSTEM_ERROR", 0}, + {"INDETERMINATE", 0}, + {"NOT_ANALYZED", 0}, + {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, + {"UNDEFINED", 0}}}, {"UncertaintyType", {{"COMBINED", 0}, {"MEAN", 0}}}, {"Uncertainty", {}}, {"AlarmLimits", {}}, @@ -135,5 +197,4 @@ {"ActivePowerSource", {}}, {"LocationNarrative", {}}, {"Thickness", {}}, - {"LocationSpatialGeographic", {}} - }; + {"LocationSpatialGeographic", {}}}; diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index f540d6131..808e0ea01 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -17,13 +17,12 @@ #pragma once -#include "../utilities.hpp" - -#include #include +#include + +#include "../utilities.hpp" namespace mtconnect::validation::observations { using Validation = std::unordered_map>; - extern Validation ControlledVocabularies; -} +} // namespace mtconnect::validation::observations diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 02c2752a2..424db8a83 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -3125,7 +3125,11 @@ TEST_F(AgentTest, should_set_validation_flag_in_header_when_version_2_5_validati PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); } +<<<<<<< HEAD +======= + +>>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); @@ -3146,7 +3150,11 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_version_below_2_ PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); } +<<<<<<< HEAD +======= + +>>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); @@ -3167,7 +3175,11 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_fa PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); } +<<<<<<< HEAD +======= + +>>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index be6699ab0..6dbfbe21c 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -21,11 +21,11 @@ #include +#include "mtconnect/asset/asset.hpp" +#include "mtconnect/device_model/data_item/data_item.hpp" #include "mtconnect/entity/entity.hpp" #include "mtconnect/observation/observation.hpp" #include "mtconnect/pipeline/validator.hpp" -#include "mtconnect/asset/asset.hpp" -#include "mtconnect/device_model/data_item/data_item.hpp" using namespace mtconnect; using namespace mtconnect::pipeline; @@ -80,18 +80,17 @@ class ObservationValidationTest : public testing::Test m_time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; ErrorList errors; - m_dataItem = DataItem::make( - {{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, - errors); + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, errors); } - void TearDown() override + void TearDown() override { m_validator.reset(); m_dataItem.reset(); m_context.reset(); } - + shared_ptr m_validator; shared_ptr m_context; DataItemPtr m_dataItem; @@ -102,7 +101,7 @@ TEST_F(ObservationValidationTest, should_validate_value) { ErrorList errors; auto event = Observation::make(m_dataItem, {{"VALUE", "READY"s}}, m_time, errors); - + auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("VALID", quality); @@ -121,7 +120,7 @@ TEST_F(ObservationValidationTest, should_detect_invalid_value) { ErrorList errors; auto event = Observation::make(m_dataItem, {{"VALUE", "FLABOR"s}}, m_time, errors); - + auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("INVALID", quality); @@ -130,14 +129,12 @@ TEST_F(ObservationValidationTest, should_detect_invalid_value) TEST_F(ObservationValidationTest, should_not_validate_unknown_type) { ErrorList errors; - m_dataItem = DataItem::make( - {{"id", "exec"s}, {"category", "EVENT"s}, {"type", "x:FLABOR"s}}, - errors); - + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "x:FLABOR"s}}, errors); + auto event = Observation::make(m_dataItem, {{"VALUE", "FLABOR"s}}, m_time, errors); - + auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("UNVERIFIABLE", quality); } - From 2b65de3b1cf090ae145d52a3dda71096836c242b Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 14:20:34 -0400 Subject: [PATCH 069/128] Added deprecated support for observations --- src/mtconnect/pipeline/validator.hpp | 7 +++- test_package/observation_validation_test.cpp | 42 +++++++++++++++++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index b99b72565..8a0660823 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -64,7 +64,12 @@ namespace mtconnect::pipeline { if (lit != lits.end()) { evt->setProperty("quality", std::string("VALID")); - // Check for deprecated + + // Check if deprecated + if (lit->second > 0 && m_contract->getSchemaVersion() > lit->second) + { + evt->setProperty("deprecated", true); + } } else { diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index 6dbfbe21c..6ba8dd6cc 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -46,13 +46,11 @@ int main(int argc, char *argv[]) class MockPipelineContract : public PipelineContract { public: - MockPipelineContract(std::map &items, int32_t schemaVersion) - : m_dataItems(items), m_schemaVersion(schemaVersion) - {} + MockPipelineContract(int32_t schemaVersion) : m_schemaVersion(schemaVersion) {} DevicePtr findDevice(const std::string &) override { return nullptr; } DataItemPtr findDataItem(const std::string &device, const std::string &name) override { - return m_dataItems[name]; + return nullptr; } void eachDataItem(EachDataItem fun) override {} void deliverObservation(observation::ObservationPtr obs) override {} @@ -65,7 +63,6 @@ class MockPipelineContract : public PipelineContract void sourceFailed(const std::string &id) override {} const ObservationPtr checkDuplicate(const ObservationPtr &obs) const override { return obs; } - std::map &m_dataItems; int32_t m_schemaVersion; }; @@ -75,6 +72,7 @@ class ObservationValidationTest : public testing::Test void SetUp() override { m_context = make_shared(); + m_context->m_contract = make_unique(SCHEMA_VERSION(2, 5)); m_validator = make_shared(m_context); m_validator->bind(make_shared(TypeGuard(RUN))); m_time = Timestamp(date::sys_days(2021_y / jan / 19_d)) + 10h + 1min; @@ -138,3 +136,37 @@ TEST_F(ObservationValidationTest, should_not_validate_unknown_type) auto quality = evt->get("quality"); ASSERT_EQ("UNVERIFIABLE", quality); } + +TEST_F(ObservationValidationTest, should_set_deprecated_flag_when_deprecated) +{ + ErrorList errors; + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, errors); + + auto event = Observation::make(m_dataItem, {{"VALUE", "PROGRAM_OPTIONAL_STOP"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); + + auto dep = evt->get("deprecated"); + ASSERT_TRUE(dep); +} + +TEST_F(ObservationValidationTest, should_not_set_deprecated_flag_when_deprecated_version_greater) +{ + ErrorList errors; + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, errors); + + auto contract = static_cast(m_context->m_contract.get()); + contract->m_schemaVersion = SCHEMA_VERSION(1, 3); + + auto event = Observation::make(m_dataItem, {{"VALUE", "PROGRAM_OPTIONAL_STOP"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); + + ASSERT_FALSE(evt->hasProperty("deprecated")); +} From a439f99917ea2635aeacdce8352d47f3fa9c09e0 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 14:30:56 -0400 Subject: [PATCH 070/128] removed version markers in agent test --- test_package/agent_test.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 424db8a83..31aaf7fa6 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -3125,11 +3125,7 @@ TEST_F(AgentTest, should_set_validation_flag_in_header_when_version_2_5_validati PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); } -<<<<<<< HEAD - -======= ->>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); @@ -3150,11 +3146,7 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_version_below_2_ PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); } -<<<<<<< HEAD - -======= ->>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); @@ -3175,11 +3167,7 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_fa PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); } -<<<<<<< HEAD - -======= ->>>>>>> e955b2c9 (Added validation header tests) { PARSE_XML_RESPONSE("/sample"); ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); From f587676098ae2e206e92574c7986a39874ebeefb Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 14:39:51 -0400 Subject: [PATCH 071/128] Do not validate tables or data sets. --- src/mtconnect/pipeline/validator.hpp | 5 ++-- test_package/observation_validation_test.cpp | 31 ++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index 8a0660823..959d465c0 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -46,13 +46,14 @@ namespace mtconnect::pipeline { auto evt = std::dynamic_pointer_cast(entity); auto di = evt->getDataItem(); - auto &value = evt->getValue(); - if (evt->isUnavailable()) + if (evt->isUnavailable() || di->isDataSet()) { evt->setProperty("quality", std::string("VALID")); } else { + auto &value = evt->getValue(); + // Optimize auto vocab = ControlledVocabularies.find(evt->getName()); if (vocab != ControlledVocabularies.end()) diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index 6ba8dd6cc..a74bb8c9f 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -170,3 +170,34 @@ TEST_F(ObservationValidationTest, should_not_set_deprecated_flag_when_deprecated ASSERT_FALSE(evt->hasProperty("deprecated")); } + + +TEST_F(ObservationValidationTest, should_not_validate_data_sets) +{ + ErrorList errors; + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}, {"representation", "DATA_SET"s}}, errors); + ASSERT_TRUE(m_dataItem->isDataSet()); + + auto event = Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); + +} + +TEST_F(ObservationValidationTest, should_not_validate_tables) +{ + ErrorList errors; + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}, {"representation", "TABLE"s}}, errors); + ASSERT_TRUE(m_dataItem->isDataSet()); + + auto event = Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("VALID", quality); + +} From e73ae12415b0cceb98699395aba32f26ff79965b Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 14:44:22 -0400 Subject: [PATCH 072/128] Formatted files --- test_package/observation_validation_test.cpp | 23 ++++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index a74bb8c9f..c7296ca40 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -171,33 +171,38 @@ TEST_F(ObservationValidationTest, should_not_set_deprecated_flag_when_deprecated ASSERT_FALSE(evt->hasProperty("deprecated")); } - TEST_F(ObservationValidationTest, should_not_validate_data_sets) { ErrorList errors; - m_dataItem = - DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}, {"representation", "DATA_SET"s}}, errors); + m_dataItem = DataItem::make({{"id", "exec"s}, + {"category", "EVENT"s}, + {"type", "EXECUTION"s}, + {"representation", "DATA_SET"s}}, + errors); ASSERT_TRUE(m_dataItem->isDataSet()); - auto event = Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); + auto event = + Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("VALID", quality); - } TEST_F(ObservationValidationTest, should_not_validate_tables) { ErrorList errors; - m_dataItem = - DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}, {"representation", "TABLE"s}}, errors); + m_dataItem = DataItem::make({{"id", "exec"s}, + {"category", "EVENT"s}, + {"type", "EXECUTION"s}, + {"representation", "TABLE"s}}, + errors); ASSERT_TRUE(m_dataItem->isDataSet()); - auto event = Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); + auto event = + Observation::make(m_dataItem, {{"VALUE", DataSet({{"field", "value"s}})}}, m_time, errors); auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("VALID", quality); - } From bc6585e942dfab15585b4c8c9747dc6805123462 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 16:06:39 -0400 Subject: [PATCH 073/128] Added some documentation --- src/mtconnect/pipeline/validator.hpp | 8 +++++++- test_package/observation_validation_test.cpp | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index 959d465c0..44c02becf 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -28,7 +28,10 @@ namespace mtconnect::pipeline { using namespace entity; - /// @brief Map a token list to data items or asset types + /// @brief Validate obsrvations based on Controlled Vocabularies + /// + /// - Does not validate data sets and tables + /// - Validates all events, not samples or conditions class AGENT_LIB_API Validator : public Transform { public: @@ -39,6 +42,9 @@ namespace mtconnect::pipeline { m_guard = TypeGuard(RUN) || TypeGuard(SKIP); } + /// @brief validate the Event + /// @param entity The Event entity + /// @returns modified entity with quality and deprecated properties EntityPtr operator()(entity::EntityPtr &&entity) override { using namespace observation; diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index c7296ca40..2c2cb3dcd 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -15,6 +15,9 @@ // limitations under the License. // +/// @file +/// Observation validation tests + // Ensure that gtest is the first header otherwise Windows raises an error #include // Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) @@ -66,6 +69,7 @@ class MockPipelineContract : public PipelineContract int32_t m_schemaVersion; }; +/// @brief Validation tests for observations class ObservationValidationTest : public testing::Test { protected: @@ -95,6 +99,7 @@ class ObservationValidationTest : public testing::Test Timestamp m_time; }; +/// @test Validate a valid value for Execution TEST_F(ObservationValidationTest, should_validate_value) { ErrorList errors; @@ -105,6 +110,7 @@ TEST_F(ObservationValidationTest, should_validate_value) ASSERT_EQ("VALID", quality); } +/// @test Unavailable should always be valid TEST_F(ObservationValidationTest, unavailable_should_be_valid) { ErrorList errors; @@ -114,6 +120,7 @@ TEST_F(ObservationValidationTest, unavailable_should_be_valid) ASSERT_EQ("VALID", quality); } +/// @test Invalid values should be marked as invalid TEST_F(ObservationValidationTest, should_detect_invalid_value) { ErrorList errors; @@ -124,6 +131,7 @@ TEST_F(ObservationValidationTest, should_detect_invalid_value) ASSERT_EQ("INVALID", quality); } +/// @test Unknown types should be unverifiable TEST_F(ObservationValidationTest, should_not_validate_unknown_type) { ErrorList errors; @@ -137,6 +145,7 @@ TEST_F(ObservationValidationTest, should_not_validate_unknown_type) ASSERT_EQ("UNVERIFIABLE", quality); } +/// @test Tag deprecated values TEST_F(ObservationValidationTest, should_set_deprecated_flag_when_deprecated) { ErrorList errors; @@ -153,6 +162,7 @@ TEST_F(ObservationValidationTest, should_set_deprecated_flag_when_deprecated) ASSERT_TRUE(dep); } +/// @test Only deprecate when the version is earlier than the current version TEST_F(ObservationValidationTest, should_not_set_deprecated_flag_when_deprecated_version_greater) { ErrorList errors; @@ -171,6 +181,7 @@ TEST_F(ObservationValidationTest, should_not_set_deprecated_flag_when_deprecated ASSERT_FALSE(evt->hasProperty("deprecated")); } +/// @test do not validate data sets TEST_F(ObservationValidationTest, should_not_validate_data_sets) { ErrorList errors; @@ -189,6 +200,7 @@ TEST_F(ObservationValidationTest, should_not_validate_data_sets) ASSERT_EQ("VALID", quality); } +/// @test do not validate tables TEST_F(ObservationValidationTest, should_not_validate_tables) { ErrorList errors; From 0f1d445bdb459e6e5be391995ada5f7436c12579 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 16:21:49 -0400 Subject: [PATCH 074/128] Added documentation for validation namespace --- src/mtconnect/validation/observations.hpp | 27 +++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index 808e0ea01..0eebdbed5 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -22,7 +22,26 @@ #include "../utilities.hpp" -namespace mtconnect::validation::observations { - using Validation = std::unordered_map>; - extern Validation ControlledVocabularies; -} // namespace mtconnect::validation::observations +namespace mtconnect { + + /// @brief MTConnect validation containers + namespace validation { + + /// @brief Observation validation containers + namespace observations { + + /// @brief Validation type for observations + using Validation = std::unordered_map>; + + /// @brief Global Validations for Event Observation's Controlled Vocabularies + /// + /// The map is as follows: + /// * Event name --> + /// * Map of valid values. Empty map if not controlled. + /// * Map has is a pair of value to + /// * 0 if not deprecated + /// * SCHEMA_VERSION if deprecated + extern Validation ControlledVocabularies; + } // namespace observations + } // namespace validation +} // namespace mtconnect From e7b8b13c5e3b254adf09771a54b5c48b336c82ed Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 16:49:56 -0400 Subject: [PATCH 075/128] Skip docker build for RC tags --- .github/workflows/build-docker-image.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-docker-image.yml b/.github/workflows/build-docker-image.yml index 33ad97758..61520b282 100644 --- a/.github/workflows/build-docker-image.yml +++ b/.github/workflows/build-docker-image.yml @@ -32,6 +32,9 @@ on: jobs: # this workflow contains a single job called "build" build: + # Do not build if it is an RC build + if: ${{ ! contains(github.ref_name, "RC") }} + # the type of runner that the job will run on runs-on: ubuntu-latest strategy: From 2d6f94968061c4e80204da8dfe614c69a7ac24a3 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 11 Apr 2024 17:47:25 -0400 Subject: [PATCH 076/128] First steps to adding routing support to websocket request. --- src/mtconnect/sink/rest_sink/request.hpp | 5 ++- src/mtconnect/sink/rest_sink/rest_service.cpp | 16 ++++--- src/mtconnect/sink/rest_sink/rest_service.hpp | 7 --- src/mtconnect/sink/rest_sink/routing.hpp | 21 +++++++-- src/mtconnect/sink/rest_sink/server.hpp | 44 +++++++++++++++---- .../sink/rest_sink/websocket_session.hpp | 6 ++- 6 files changed, 73 insertions(+), 26 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index 9a24e2239..164ddcd33 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -67,7 +67,10 @@ namespace mtconnect::sink::rest_sink { uint16_t m_foreignPort; ///< The requestors Port QueryMap m_query; ///< The parsed query parameters ParameterMap m_parameters; ///< The parsed path parameters - bool m_parsed { false }; ///< Flag the request as parsed + + std::optional m_requestId; ///< Request id from websocket sub + std::optional m_command; ///< Specific request from websocket + /// @brief Find a parameter by type /// @tparam T the type of the parameter diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 4b8167b9c..6c202c337 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -122,7 +122,8 @@ namespace mtconnect { createAssetRoutings(); createPutObservationRoutings(); createFileRoutings(); - + m_server->addCommands(); + makeLoopbackSource(m_sinkContract->m_pipelineContext); } @@ -499,7 +500,8 @@ namespace mtconnect { "/{device}/probe?pretty={bool:false}&deviceType={string}", handler}) .document("MTConnect probe request", "Provides metadata service for the MTConnect Devices information model for " - "device identified by `device` matching `name` or `uuid`."); + "device identified by `device` matching `name` or `uuid`.") + .command("probe"); // Must be last m_server @@ -645,7 +647,9 @@ namespace mtconnect { "/{device}/" + asset + "?type={string}", deleteHandler}) .document("Delete all assets for a device and type", "Device and type are optional. If they are not given, it assumes there is " - "no constraint"); + "no constraint") + .command("asset"); +; } } } @@ -685,7 +689,8 @@ namespace mtconnect { m_server->addRouting({boost::beast::http::verb::get, "/{device}/current?" + qp, handler}) .document("MTConnect current request", "Gets a stapshot of the state of all the observations for device `device` " - "optionally filtered by the `path`"); + "optionally filtered by the `path`") + .command("current"); } void RestService::createSampleRoutings() @@ -730,7 +735,8 @@ namespace mtconnect { .document("MTConnect sample request", "Gets a time series of at maximum `count` observations for device `device` " "optionally filtered by the `path` and starting at `from`. By default, from is " - "the first available observation known to the agent"); + "the first available observation known to the agent") + .command("sample"); } void RestService::createPutObservationRoutings() diff --git a/src/mtconnect/sink/rest_sink/rest_service.hpp b/src/mtconnect/sink/rest_sink/rest_service.hpp index 51505fd51..923f210df 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.hpp +++ b/src/mtconnect/sink/rest_sink/rest_service.hpp @@ -321,22 +321,15 @@ namespace mtconnect { protected: // Loopback boost::asio::io_context &m_context; - boost::asio::io_context::strand m_strand; - std::string m_schemaVersion; - ConfigOptions m_options; - std::shared_ptr m_loopback; - uint64_t m_instanceId; - std::unique_ptr m_server; // Buffers FileCache m_fileCache; - bool m_logStreamData {false}; }; } // namespace sink::rest_sink diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index ca8bdf38d..5b235b56d 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -53,8 +53,8 @@ namespace mtconnect::sink::rest_sink { /// @param[in] function the function to call if matches /// @param[in] swagger `true` if swagger related Routing(boost::beast::http::verb verb, const std::string &pattern, const Function function, - bool swagger = false) - : m_verb(verb), m_function(function), m_swagger(swagger) + bool swagger = false, std::optional request = std::nullopt) + : m_verb(verb), m_command(request), m_function(function), m_swagger(swagger) { std::string s(pattern); @@ -79,8 +79,8 @@ namespace mtconnect::sink::rest_sink { /// @param[in] function the function to call if matches /// @param[in] swagger `true` if swagger related Routing(boost::beast::http::verb verb, const std::regex &pattern, const Function function, - bool swagger = false) - : m_verb(verb), m_pattern(pattern), m_function(function), m_swagger(swagger) + bool swagger = false, std::optional request = std::nullopt) + : m_verb(verb), m_pattern(pattern), m_command(request), m_function(function), m_swagger(swagger) {} /// @brief Added summary and description to the routing @@ -224,6 +224,17 @@ namespace mtconnect::sink::rest_sink { const auto &getPath() const { return m_path; } /// @brief Get the routing `verb` const auto &getVerb() const { return m_verb; } + + /// @brief Get the optional command associated with the routing + /// @returns optional routing + const auto &getCommand() const { return m_command; } + + /// @brief Sets the command associated with this routing for use with websockets + /// @param command the command + void command(const std::string &command) + { + m_command = command; + } protected: void pathParameters(std::string s) @@ -360,7 +371,9 @@ namespace mtconnect::sink::rest_sink { std::optional m_path; ParameterList m_pathParameters; QuerySet m_queryParameters; + std::optional m_command; Function m_function; + std::optional m_summary; std::optional m_description; diff --git a/src/mtconnect/sink/rest_sink/server.hpp b/src/mtconnect/sink/rest_sink/server.hpp index d72fd1764..9e5987aa2 100644 --- a/src/mtconnect/sink/rest_sink/server.hpp +++ b/src/mtconnect/sink/rest_sink/server.hpp @@ -159,16 +159,31 @@ namespace mtconnect::sink::rest_sink { { try { - for (auto &r : m_routings) + if (request->m_command) { - if (r.matches(session, request)) - return true; + auto route = m_commands.find(*request->m_command); + if (route != m_commands.end()) + { + + } + + std::stringstream txt; + txt << session->getRemote().address() << ": Cannot find handler for command: " << *request->m_command; + session->fail(boost::beast::http::status::not_found, txt.str()); + } + else + { + for (auto &r : m_routings) + { + if (r.matches(session, request)) + return true; + } + + std::stringstream txt; + txt << session->getRemote().address() << ": Cannot find handler for: " << request->m_verb + << " " << request->m_path; + session->fail(boost::beast::http::status::not_found, txt.str()); } - - std::stringstream txt; - txt << session->getRemote().address() << ": Cannot find handler for: " << request->m_verb - << " " << request->m_path; - session->fail(boost::beast::http::status::not_found, txt.str()); } catch (RequestError &re) { @@ -217,8 +232,20 @@ namespace mtconnect::sink::rest_sink { auto &route = m_routings.emplace_back(routing); if (m_parameterDocumentation) route.documentParameters(*m_parameterDocumentation); + if (route.getCommand()) + m_commands.emplace(*route.getCommand(), &route); return route; } + + /// @brief Setup commands from routings + void addCommands() + { + for (auto &route : m_routings) + { + if (route.getCommand()) + m_commands.emplace(*route.getCommand(), &route); + } + } /// @brief Add common set of documentation for all rest routings /// @param[in] docs Parameter documentation @@ -272,6 +299,7 @@ namespace mtconnect::sink::rest_sink { std::set m_allowPutsFrom; std::list m_routings; + std::map m_commands; std::unique_ptr m_fileCache; ErrorFunction m_errorFunction; FieldList m_fields; diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 2d87ced24..46043fe20 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -192,7 +192,11 @@ namespace mtconnect::sink::rest_sink { } } - m_request->m_parsed = true; + if (object.HasMember("command")) + request->m_command = object["command"].GetString(); + if (object.HasMember("id")) + request->m_requestId = object["id"].GetString(); + if (!m_dispatch(derived().shared_ptr(), m_request)) { ostringstream txt; From bf9f8b46d4c57afe3f815a7be91b85a9646d2d94 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 12 Apr 2024 12:39:49 -0400 Subject: [PATCH 077/128] Changed from command to request --- src/mtconnect/sink/rest_sink/websocket_session.hpp | 4 ++-- test_package/resources/samples/test_config.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 46043fe20..add1a6d99 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -192,8 +192,8 @@ namespace mtconnect::sink::rest_sink { } } - if (object.HasMember("command")) - request->m_command = object["command"].GetString(); + if (object.HasMember("request")) + request->m_command = object["request"].GetString(); if (object.HasMember("id")) request->m_requestId = object["id"].GetString(); diff --git a/test_package/resources/samples/test_config.xml b/test_package/resources/samples/test_config.xml index b42a291c7..cda9baf07 100644 --- a/test_package/resources/samples/test_config.xml +++ b/test_package/resources/samples/test_config.xml @@ -1,6 +1,6 @@ -
+
Linux CNC Device From a4472b139a23a1dabe4fb4b864f7f8333cb8e25f Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Tue, 16 Apr 2024 10:11:40 -0400 Subject: [PATCH 078/128] working to the point of response --- README.md | 12 +++- src/mtconnect/sink/rest_sink/routing.hpp | 57 ++++++++++--------- src/mtconnect/sink/rest_sink/server.hpp | 13 +++-- .../sink/rest_sink/websocket_session.hpp | 55 +++++++++++++----- 4 files changed, 90 insertions(+), 47 deletions(-) diff --git a/README.md b/README.md index 00c2d1163..2484efb09 100755 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -MTConnect C++ Agent Version 2.3 +MTConnect C++ Agent Version 2.5 -------- [![Build MTConnect C++ Agent](https://github.com/mtconnect/cppagent/actions/workflows/build.yml/badge.svg)](https://github.com/mtconnect/cppagent/actions/workflows/build.yml) @@ -13,6 +13,10 @@ the devices and the location of the adapter. Pre-built binary releases for Windows are available from [Releases](https://github.com/mtconnect/cppagent/releases) for those who do not want to build the agent themselves. For *NIX users, you will need libxml2, cppunit, and cmake as well as build essentials. +Version 2.5.0 Added validation of observations in the stream + +Version 2.4.0 Added support for version 2.4 + Version 2.3.0 Support for all Version 2.3 standard changes and JSON ingress to MQTT adapter. Version 2.2.0 Support for all Version 2.2 standard changes and dynamic configuration from adapters. Upgrade to conan 2. @@ -667,11 +671,17 @@ Configuration Parameters * `VersionDeviceXml` - Create a new versioned file every time the Device.xml file changes from an external source. *Default*: `false` + +* `Validation` - Turns on validation of model components and observations + + *Default*: `false` * `WorkerThreads` - The number of operating system threads dedicated to the Agent *Default*: 1 + + #### Adapter General Configuration These can be overridden on a per-adapter basis diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index 5b235b56d..f4048ea1f 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -165,46 +165,49 @@ namespace mtconnect::sink::rest_sink { { try { - request->m_parameters.clear(); - std::smatch m; - if (m_verb == request->m_verb && std::regex_match(request->m_path, m, m_pattern)) + if (!request->m_command) { - auto s = m.begin(); - s++; - for (auto &p : m_pathParameters) + request->m_parameters.clear(); + std::smatch m; + if (m_verb == request->m_verb && std::regex_match(request->m_path, m, m_pattern)) { - if (s != m.end()) + auto s = m.begin(); + s++; + for (auto &p : m_pathParameters) { - ParameterValue v(s->str()); - request->m_parameters.emplace(make_pair(p.m_name, v)); - s++; + if (s != m.end()) + { + ParameterValue v(s->str()); + request->m_parameters.emplace(make_pair(p.m_name, v)); + s++; + } } } + } - for (auto &p : m_queryParameters) + for (auto &p : m_queryParameters) + { + auto q = request->m_query.find(p.m_name); + if (q != request->m_query.end()) { - auto q = request->m_query.find(p.m_name); - if (q != request->m_query.end()) + try { - try - { - auto v = convertValue(q->second, p.m_type); - request->m_parameters.emplace(make_pair(p.m_name, v)); - } - catch (ParameterError &e) - { - std::string msg = - std::string("for query parameter '") + p.m_name + "': " + e.what(); - throw ParameterError(msg); - } + auto v = convertValue(q->second, p.m_type); + request->m_parameters.emplace(make_pair(p.m_name, v)); } - else if (!std::holds_alternative(p.m_default)) + catch (ParameterError &e) { - request->m_parameters.emplace(make_pair(p.m_name, p.m_default)); + std::string msg = + std::string("for query parameter '") + p.m_name + "': " + e.what(); + throw ParameterError(msg); } } - return m_function(session, request); + else if (!std::holds_alternative(p.m_default)) + { + request->m_parameters.emplace(make_pair(p.m_name, p.m_default)); + } } + return m_function(session, request); } catch (ParameterError &e) diff --git a/src/mtconnect/sink/rest_sink/server.hpp b/src/mtconnect/sink/rest_sink/server.hpp index 9e5987aa2..2adde6599 100644 --- a/src/mtconnect/sink/rest_sink/server.hpp +++ b/src/mtconnect/sink/rest_sink/server.hpp @@ -164,12 +164,15 @@ namespace mtconnect::sink::rest_sink { auto route = m_commands.find(*request->m_command); if (route != m_commands.end()) { - + if (route->second->matches(session, request)) + return true; + } + else + { + std::stringstream txt; + txt << session->getRemote().address() << ": Cannot find handler for command: " << *request->m_command; + session->fail(boost::beast::http::status::not_found, txt.str()); } - - std::stringstream txt; - txt << session->getRemote().address() << ": Cannot find handler for command: " << *request->m_command; - session->fail(boost::beast::http::status::not_found, txt.str()); } else { diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index add1a6d99..aabb473f1 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -85,7 +85,17 @@ namespace mtconnect::sink::rest_sink { void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { + beast::flat_buffer buf; + buf.prepare(response->m_body.size()); + buf. + + ws_.async_write( + buf.data(), + beast::bind_front_handler( + &WebsocketSession::sent, + derived().shared_ptr())); + } void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override @@ -122,6 +132,12 @@ namespace mtconnect::sink::rest_sink { } + void sent(beast::error_code ec, + std::size_t len) + { + + } + void onRead(beast::error_code ec, std::size_t len) { @@ -132,6 +148,7 @@ namespace mtconnect::sink::rest_sink { // REST API derived().stream().text(derived().stream().got_text()); auto buffer = beast::buffers_to_string(m_buffer.data()); + m_buffer.consume(m_buffer.size()); Document doc; doc.Parse(buffer.c_str(), len); @@ -151,8 +168,7 @@ namespace mtconnect::sink::rest_sink { { // Extract the parameters from the json doc to map them to the REST // protocol parameters - auto request = std::make_shared(); - request->m_verb = beast::http::verb::get; + m_request->m_verb = beast::http::verb::get; const auto &object = doc.GetObject(); for (auto &it : object) @@ -163,39 +179,50 @@ namespace mtconnect::sink::rest_sink { // Skip nulls break; case rapidjson::kFalseType: - request->m_parameters.emplace(make_pair(it.name.GetString(), false)); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), false)); break; case rapidjson::kTrueType: - request->m_parameters.emplace(make_pair(it.name.GetString(), true)); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), true)); break; case rapidjson::kObjectType: break; case rapidjson::kArrayType: break; case rapidjson::kStringType: - request->m_parameters.emplace(make_pair(it.name.GetString(), string(it.value.GetString()))); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), string(it.value.GetString()))); break; case rapidjson::kNumberType: if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), (uint64_t) it.value.Get())); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), (uint64_t) it.value.Get())); else if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); break; } } - if (object.HasMember("request")) - request->m_command = object["request"].GetString(); - if (object.HasMember("id")) - request->m_requestId = object["id"].GetString(); + if (m_request->m_parameters.count("request") > 0) + { + m_request->m_command = get(m_request->m_parameters["request"]); + m_request->m_parameters.erase("request"); + } + if (m_request->m_parameters.count("id") > 0) + { + auto &v =m_request->m_parameters["id"]; + string id = visit(overloaded { + [](monostate m) { return ""s; }, + [](auto v) { return boost::lexical_cast(v); } + }, v); + m_request->m_requestId = id; + m_request->m_parameters.erase("id"); + } if (!m_dispatch(derived().shared_ptr(), m_request)) { From 060dd0b412408946e514f1ad8b6c7a427f67c817 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Tue, 16 Apr 2024 14:56:08 -0400 Subject: [PATCH 079/128] checkpoint with write response --- src/mtconnect/mqtt/mqtt_client_impl.hpp | 3 + src/mtconnect/sink/rest_sink/request.hpp | 5 +- src/mtconnect/sink/rest_sink/response.hpp | 1 + src/mtconnect/sink/rest_sink/rest_service.cpp | 58 ++-- src/mtconnect/sink/rest_sink/routing.hpp | 19 +- src/mtconnect/sink/rest_sink/server.hpp | 9 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 27 +- src/mtconnect/sink/rest_sink/session_impl.hpp | 9 +- .../sink/rest_sink/websocket_session.hpp | 272 ++++++++++-------- src/mtconnect/validation/observations.hpp | 6 +- 10 files changed, 220 insertions(+), 189 deletions(-) diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index 3997a4477..f1d7273c6 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -162,6 +162,9 @@ namespace mtconnect { LOG(info) << "MQTT " << m_url << ": connection closed"; // Queue on a strand m_connected = false; + if (m_handler && m_handler->m_disconnected) + m_handler->m_disconnected(shared_from_this()); + m_handler->m_disconnected(shared_from_this()); if (m_running) { disconnected(); diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index 164ddcd33..ac3f2c33b 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -68,9 +68,8 @@ namespace mtconnect::sink::rest_sink { QueryMap m_query; ///< The parsed query parameters ParameterMap m_parameters; ///< The parsed path parameters - std::optional m_requestId; ///< Request id from websocket sub - std::optional m_command; ///< Specific request from websocket - + std::optional m_requestId; ///< Request id from websocket sub + std::optional m_command; ///< Specific request from websocket /// @brief Find a parameter by type /// @tparam T the type of the parameter diff --git a/src/mtconnect/sink/rest_sink/response.hpp b/src/mtconnect/sink/rest_sink/response.hpp index a67bdbe6b..b19fecff1 100644 --- a/src/mtconnect/sink/rest_sink/response.hpp +++ b/src/mtconnect/sink/rest_sink/response.hpp @@ -64,6 +64,7 @@ namespace mtconnect { std::chrono::seconds m_expires; ///< how long should this session should stay open before it is closed bool m_close {false}; ///< `true` if this session should closed after it responds + std::optional m_requestId; ///< Request id from websocket sub CachedFilePtr m_file; ///< Cached file if a file is being returned }; diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 6c202c337..83401420e 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -123,7 +123,7 @@ namespace mtconnect { createPutObservationRoutings(); createFileRoutings(); m_server->addCommands(); - + makeLoopbackSource(m_sinkContract->m_pipelineContext); } @@ -435,8 +435,10 @@ namespace mtconnect { // Request Routings // ----------------------------------------------------------- - static inline void respond(rest_sink::SessionPtr session, rest_sink::ResponsePtr &&response) + static inline void respond(rest_sink::SessionPtr session, rest_sink::ResponsePtr &&response, + std::optional id = std::nullopt) { + response->m_requestId = id; session->writeResponse(std::move(response)); } @@ -485,7 +487,7 @@ namespace mtconnect { return false; } - respond(session, probeRequest(printer, device, pretty, deviceType)); + respond(session, probeRequest(printer, device, pretty, deviceType), request->m_requestId); return true; }; @@ -527,8 +529,10 @@ namespace mtconnect { auto printer = printerForAccepts(request->m_accepts); auto pretty = request->parameter("pretty").value_or(false); - respond(session, assetRequest(printer, count, removed, request->parameter("type"), - request->parameter("device"), pretty)); + respond(session, + assetRequest(printer, count, removed, request->parameter("type"), + request->parameter("device"), pretty), + request->m_requestId); return true; }; @@ -544,15 +548,16 @@ namespace mtconnect { string id; while (getline(str, id, ';')) ids.emplace_back(id); - respond(session, assetIdsRequest(printer, ids, pretty)); + respond(session, assetIdsRequest(printer, ids, pretty), request->m_requestId); } else { auto printer = printerForAccepts(request->m_accepts); auto pretty = *request->parameter("pretty"); auto error = printError(printer, "INVALID_REQUEST", "No asset given", pretty); - respond(session, make_unique(rest_sink::status::bad_request, error, - printer->mimeType())); + respond(session, + make_unique(rest_sink::status::bad_request, error, printer->mimeType()), + request->m_requestId); } return true; }; @@ -584,7 +589,8 @@ namespace mtconnect { respond(session, putAssetRequest(printer, request->m_body, request->parameter("type"), request->parameter("device"), - request->parameter("assetId"))); + request->parameter("assetId")), + request->m_requestId); return true; }; @@ -599,13 +605,15 @@ namespace mtconnect { while (getline(str, id, ';')) ids.emplace_back(id); - respond(session, deleteAssetRequest(printer, ids)); + respond(session, deleteAssetRequest(printer, ids), request->m_requestId); } else { - respond(session, deleteAllAssetsRequest(printerForAccepts(request->m_accepts), - request->parameter("device"), - request->parameter("type"))); + respond(session, + deleteAllAssetsRequest(printerForAccepts(request->m_accepts), + request->parameter("device"), + request->parameter("type")), + request->m_requestId); } return true; }; @@ -649,7 +657,7 @@ namespace mtconnect { "Device and type are optional. If they are not given, it assumes there is " "no constraint") .command("asset"); -; + ; } } } @@ -668,12 +676,13 @@ namespace mtconnect { } else { - respond(session, currentRequest(printerForAccepts(request->m_accepts), - request->parameter("device"), - request->parameter("at"), - request->parameter("path"), - *request->parameter("pretty"), - request->parameter("deviceType"))); + respond( + session, + currentRequest( + printerForAccepts(request->m_accepts), request->parameter("device"), + request->parameter("at"), request->parameter("path"), + *request->parameter("pretty"), request->parameter("deviceType")), + request->m_requestId); } return true; }; @@ -715,7 +724,8 @@ namespace mtconnect { printerForAccepts(request->m_accepts), *request->parameter("count"), request->parameter("device"), request->parameter("from"), request->parameter("to"), request->parameter("path"), - *request->parameter("pretty"), request->parameter("deviceType"))); + *request->parameter("pretty"), request->parameter("deviceType")), + request->m_requestId); } return true; }; @@ -754,8 +764,10 @@ namespace mtconnect { queries.erase("time"); auto device = request->parameter("device"); - respond(session, putObservationRequest(printerForAccepts(request->m_accepts), *device, - queries, ts)); + respond( + session, + putObservationRequest(printerForAccepts(request->m_accepts), *device, queries, ts), + request->m_requestId); return true; } else diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index f4048ea1f..230534222 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -80,7 +80,11 @@ namespace mtconnect::sink::rest_sink { /// @param[in] swagger `true` if swagger related Routing(boost::beast::http::verb verb, const std::regex &pattern, const Function function, bool swagger = false, std::optional request = std::nullopt) - : m_verb(verb), m_pattern(pattern), m_command(request), m_function(function), m_swagger(swagger) + : m_verb(verb), + m_pattern(pattern), + m_command(request), + m_function(function), + m_swagger(swagger) {} /// @brief Added summary and description to the routing @@ -197,8 +201,7 @@ namespace mtconnect::sink::rest_sink { } catch (ParameterError &e) { - std::string msg = - std::string("for query parameter '") + p.m_name + "': " + e.what(); + std::string msg = std::string("for query parameter '") + p.m_name + "': " + e.what(); throw ParameterError(msg); } } @@ -227,17 +230,14 @@ namespace mtconnect::sink::rest_sink { const auto &getPath() const { return m_path; } /// @brief Get the routing `verb` const auto &getVerb() const { return m_verb; } - + /// @brief Get the optional command associated with the routing /// @returns optional routing const auto &getCommand() const { return m_command; } - + /// @brief Sets the command associated with this routing for use with websockets /// @param command the command - void command(const std::string &command) - { - m_command = command; - } + void command(const std::string &command) { m_command = command; } protected: void pathParameters(std::string s) @@ -376,7 +376,6 @@ namespace mtconnect::sink::rest_sink { QuerySet m_queryParameters; std::optional m_command; Function m_function; - std::optional m_summary; std::optional m_description; diff --git a/src/mtconnect/sink/rest_sink/server.hpp b/src/mtconnect/sink/rest_sink/server.hpp index 2adde6599..740efab83 100644 --- a/src/mtconnect/sink/rest_sink/server.hpp +++ b/src/mtconnect/sink/rest_sink/server.hpp @@ -170,7 +170,8 @@ namespace mtconnect::sink::rest_sink { else { std::stringstream txt; - txt << session->getRemote().address() << ": Cannot find handler for command: " << *request->m_command; + txt << session->getRemote().address() + << ": Cannot find handler for command: " << *request->m_command; session->fail(boost::beast::http::status::not_found, txt.str()); } } @@ -184,7 +185,7 @@ namespace mtconnect::sink::rest_sink { std::stringstream txt; txt << session->getRemote().address() << ": Cannot find handler for: " << request->m_verb - << " " << request->m_path; + << " " << request->m_path; session->fail(boost::beast::http::status::not_found, txt.str()); } } @@ -239,7 +240,7 @@ namespace mtconnect::sink::rest_sink { m_commands.emplace(*route.getCommand(), &route); return route; } - + /// @brief Setup commands from routings void addCommands() { @@ -302,7 +303,7 @@ namespace mtconnect::sink::rest_sink { std::set m_allowPutsFrom; std::list m_routings; - std::map m_commands; + std::map m_commands; std::unique_ptr m_fileCache; ErrorFunction m_errorFunction; FieldList m_fields; diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index 52651e384..d84c43fd7 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -198,7 +198,7 @@ namespace mtconnect::sink::rest_sink { auto &msg = m_parser->get(); const auto &remote = beast::get_lowest_layer(derived().stream()).socket().remote_endpoint(); - + // Check for put, post, or delete if (msg.method() != http::verb::get) { @@ -244,7 +244,7 @@ namespace mtconnect::sink::rest_sink { LOG(info) << "ReST Request: From [" << m_request->m_foreignIp << ':' << remote.port() << "]: " << msg.method() << " " << msg.target(); - + // Check if this is a websocket upgrade request. If so, begin a websocket session. if (ws::is_upgrade(msg)) { @@ -469,17 +469,13 @@ namespace mtconnect::sink::rest_sink { writeResponse(std::move(response)); } } - + SessionPtr HttpSession::upgradeToWebsocket(RequestMessage &&msg) { - return std::make_shared(std::move(m_stream), - std::move(m_request), - std::move(msg), - m_dispatch, - m_errorFunction); + return std::make_shared(std::move(m_stream), std::move(m_request), + std::move(msg), m_dispatch, m_errorFunction); } - /// @brief A secure https session class HttpsSession : public SessionImpl { @@ -536,15 +532,12 @@ namespace mtconnect::sink::rest_sink { m_stream.async_shutdown(beast::bind_front_handler(&HttpsSession::shutdown, shared_ptr())); } } - + /// @brief Upgrade the current connection to a websocket connection. SessionPtr upgradeToWebsocket(RequestMessage &&msg) { - return std::make_shared(std::move(m_stream), - std::move(m_request), - std::move(msg), - m_dispatch, - m_errorFunction); + return std::make_shared(std::move(m_stream), std::move(m_request), + std::move(msg), m_dispatch, m_errorFunction); } protected: @@ -569,8 +562,8 @@ namespace mtconnect::sink::rest_sink { beast::ssl_stream m_stream; bool m_closing {false}; }; - - template + + template void SessionImpl::upgrade(RequestMessage &&msg) { LOG(debug) << "Upgrading session to websockets"; diff --git a/src/mtconnect/sink/rest_sink/session_impl.hpp b/src/mtconnect/sink/rest_sink/session_impl.hpp index 27be34970..07ab7fbd0 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.hpp +++ b/src/mtconnect/sink/rest_sink/session_impl.hpp @@ -35,12 +35,11 @@ namespace mtconnect { } namespace sink::rest_sink { - template + template class WebsocketSession; - template + template using WebsocketSessionPtr = std::shared_ptr>; - - + /// @brief A session implementation `Derived` subclass pattern /// @tparam subclass of this class to use the same methods with http or https protocol streams template @@ -153,7 +152,7 @@ namespace mtconnect { boost::beast::error_code ec; m_stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); } - + /// @brief Upgrade the current connection to a websocket connection. SessionPtr upgradeToWebsocket(RequestMessage &&msg); diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index aabb473f1..f39b559e5 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -20,12 +20,11 @@ #include #include -#include -#include - #include #include #include +#include +#include #include "mtconnect/config.hpp" #include "mtconnect/configuration/config_options.hpp" @@ -34,18 +33,26 @@ namespace mtconnect::sink::rest_sink { namespace beast = boost::beast; - + + struct WebsocketRequest + { + std::string m_requestId; + std::optional m_streamBuffer; + Complete m_complete; + bool m_streaming {false}; + }; + /// @brief A websocket session that provides a pubsub interface using REST parameters - template + template class WebsocketSession : public Session { public: using RequestMessage = boost::beast::http::request; - WebsocketSession(RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) - : Session(dispatch, func), m_request(std::move(request)), m_msg(std::move(msg)) - { - } + WebsocketSession(RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, + ErrorFunction func) + : Session(dispatch, func), m_request(std::move(request)), m_msg(std::move(msg)) + {} /// @brief Session cannot be copied. WebsocketSession(const WebsocketSession &) = delete; @@ -54,67 +61,69 @@ namespace mtconnect::sink::rest_sink { /// @brief get this as the `Derived` type /// @return the subclass Derived &derived() { return static_cast(*this); } - - + void run() override { using namespace boost::beast; - + // Set suggested timeout settings for the websocket derived().stream().set_option( - websocket::stream_base::timeout::suggested( - beast::role_type::server)); + websocket::stream_base::timeout::suggested(beast::role_type::server)); // Set a decorator to change the Server of the handshake derived().stream().set_option( - websocket::stream_base::decorator( - [](websocket::response_type& res) - { - res.set(http::field::server, - GetAgentVersion() + - " MTConnectAgent"); + websocket::stream_base::decorator([](websocket::response_type &res) { + res.set(http::field::server, GetAgentVersion() + " MTConnectAgent"); })); // Accept the websocket handshake derived().stream().async_accept( - m_msg, - beast::bind_front_handler( - &WebsocketSession::onAccept, - derived().shared_ptr())); + m_msg, beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr())); } void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { - beast::flat_buffer buf; - - buf.prepare(response->m_body.size()); - buf. - - ws_.async_write( - buf.data(), - beast::bind_front_handler( - &WebsocketSession::sent, - derived().shared_ptr())); + if (response->m_requestId) + { + auto id = *(response->m_requestId); + auto it = m_requests.find(id); + if (it != m_requests.end()) + { + using namespace std::placeholders; + auto &req = it->second; + req.m_complete = complete; + req.m_streamBuffer.emplace(); + std::ostream str(&req.m_streamBuffer.value()); + + str << response->m_body; + + derived().stream().text(derived().stream().got_text()); + derived().stream().async_write( + req.m_streamBuffer->data(), + beast::bind_handler( + [this, id](beast::error_code ec, std::size_t len) { sent(ec, len, id); }, _1, + _2)); + } + else + { + LOG(error) << "WebsocketSession::writeResponse: Cannot find request for id: " << id; + } + } + else + { + LOG(error) << "WebsocketSession::writeResponse: No request id for websocket"; + } } - - void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override - { - } - - void beginStreaming(const std::string &mimeType, Complete complete) override - { - } - - void writeChunk(const std::string &chunk, Complete complete) override - { - - } - - void closeStream() override - { - } - + + void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override {} + + void beginStreaming(const std::string &mimeType, Complete complete) override {} + + void writeChunk(const std::string &chunk, Complete complete) override {} + + void closeStream() override {} + protected: void onAccept(boost::beast::error_code ec) { @@ -123,40 +132,54 @@ namespace mtconnect::sink::rest_sink { fail(status::internal_server_error, "Error occurred in accpet", ec); return; } - - derived().stream().async_read( - m_buffer, - beast::bind_front_handler( - &WebsocketSession::onRead, - derived().shared_ptr())); + derived().stream().async_read( + m_buffer, beast::bind_front_handler(&WebsocketSession::onRead, derived().shared_ptr())); } - - void sent(beast::error_code ec, - std::size_t len) + + void sent(beast::error_code ec, std::size_t len, const std::string &id) { - + auto it = m_requests.find(id); + if (it != m_requests.end()) + { + auto &req = it->second; + if (req.m_complete) + { + req.m_complete(); + } + + if (!req.m_streaming) + { + m_requests.erase(id); + } + } + else + { + LOG(error) << "WebsocketSession::sent: Cannot find request for id: " << id; + } } - - void onRead(beast::error_code ec, - std::size_t len) + + void onRead(beast::error_code ec, std::size_t len) { + if (ec) + return fail(boost::beast::http::status::internal_server_error, "shutdown", ec); + using namespace rapidjson; using namespace std; - + // Parse the buffer as a JSON request with parameters matching // REST API derived().stream().text(derived().stream().got_text()); auto buffer = beast::buffers_to_string(m_buffer.data()); m_buffer.consume(m_buffer.size()); - + Document doc; doc.Parse(buffer.c_str(), len); - + if (doc.HasParseError()) { - LOG(warning) << "Websocket Read Error(offset (" << doc.GetErrorOffset() << "): " << - GetParseError_En(doc.GetParseError()); + LOG(warning) << "Websocket Read Error(offset (" << doc.GetErrorOffset() + << "): " << GetParseError_En(doc.GetParseError()); LOG(warning) << " " << buffer; } if (!doc.IsObject()) @@ -170,7 +193,7 @@ namespace mtconnect::sink::rest_sink { // protocol parameters m_request->m_verb = beast::http::verb::get; const auto &object = doc.GetObject(); - + for (auto &it : object) { switch (it.value.GetType()) @@ -185,29 +208,35 @@ namespace mtconnect::sink::rest_sink { m_request->m_parameters.emplace(make_pair(it.name.GetString(), true)); break; case rapidjson::kObjectType: - break; + break; case rapidjson::kArrayType: break; case rapidjson::kStringType: - m_request->m_parameters.emplace(make_pair(it.name.GetString(), string(it.value.GetString()))); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), string(it.value.GetString()))); break; case rapidjson::kNumberType: if (it.value.Is()) - m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace(make_pair(it.name.GetString(), (uint64_t) it.value.Get())); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), (uint64_t)it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + m_request->m_parameters.emplace( + make_pair(it.name.GetString(), it.value.Get())); break; } } - + if (m_request->m_parameters.count("request") > 0) { m_request->m_command = get(m_request->m_parameters["request"]); @@ -215,15 +244,17 @@ namespace mtconnect::sink::rest_sink { } if (m_request->m_parameters.count("id") > 0) { - auto &v =m_request->m_parameters["id"]; - string id = visit(overloaded { - [](monostate m) { return ""s; }, - [](auto v) { return boost::lexical_cast(v); } - }, v); + auto &v = m_request->m_parameters["id"]; + string id = visit(overloaded {[](monostate m) { return ""s; }, + [](auto v) { return boost::lexical_cast(v); }}, + v); m_request->m_requestId = id; m_request->m_parameters.erase("id"); } + auto &req = m_requests[*(m_request->m_requestId)]; + req.m_requestId = *(m_request->m_requestId); + if (!m_dispatch(derived().shared_ptr(), m_request)) { ostringstream txt; @@ -231,45 +262,42 @@ namespace mtconnect::sink::rest_sink { LOG(error) << txt.str(); } } - + derived().stream().async_read( - m_buffer, - beast::bind_front_handler( - &WebsocketSession::onRead, - derived().shared_ptr())); + m_buffer, beast::bind_front_handler(&WebsocketSession::onRead, derived().shared_ptr())); } - + protected: RequestPtr m_request; RequestMessage m_msg; beast::flat_buffer m_buffer; + std::map m_requests; }; - - template + + template using WebsocketSessionPtr = std::shared_ptr>; - + class PlainWebsocketSession : public WebsocketSession { public: using Stream = beast::websocket::stream; - - PlainWebsocketSession(beast::tcp_stream&& stream, RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) - : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) - { - } - ~PlainWebsocketSession() - { - close(); - } - + + PlainWebsocketSession(beast::tcp_stream &&stream, RequestPtr &&request, RequestMessage &&msg, + Dispatch dispatch, ErrorFunction func) + : WebsocketSession(std::move(request), std::move(msg), dispatch, func), + m_stream(std::move(stream)) + {} + ~PlainWebsocketSession() { close(); } + void close() override { NAMED_SCOPE("PlainWebsocketSession::close"); - + m_request.reset(); - m_stream.close(beast::websocket::close_code::none); + if (m_stream.is_open()) + m_stream.close(beast::websocket::close_code::none); } - + auto &stream() { return m_stream; } /// @brief Get a pointer cast as an Websocket Session @@ -278,37 +306,34 @@ namespace mtconnect::sink::rest_sink { { return std::dynamic_pointer_cast(shared_from_this()); } - - - + protected: Stream m_stream; }; - + class TlsWebsocketSession : public WebsocketSession { public: using Stream = beast::websocket::stream>; - - TlsWebsocketSession(beast::ssl_stream&& stream, RequestPtr &&request, RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) - : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) - { - } - ~TlsWebsocketSession() - { - close(); - } + + TlsWebsocketSession(beast::ssl_stream &&stream, RequestPtr &&request, + RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) + : WebsocketSession(std::move(request), std::move(msg), dispatch, func), + m_stream(std::move(stream)) + {} + ~TlsWebsocketSession() { close(); } auto &stream() { return m_stream; } - + void close() override { NAMED_SCOPE("TlsWebsocketSession::close"); m_request.reset(); - m_stream.close(beast::websocket::close_code::none); + if (m_stream.is_open()) + m_stream.close(beast::websocket::close_code::none); } - + /// @brief Get a pointer cast as an TLS Websocket Session /// @return shared pointer to an TLS Websocket session std::shared_ptr shared_ptr() @@ -319,6 +344,5 @@ namespace mtconnect::sink::rest_sink { protected: Stream m_stream; }; - -} +} // namespace mtconnect::sink::rest_sink diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index 0eebdbed5..c5a843edd 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -23,13 +23,13 @@ #include "../utilities.hpp" namespace mtconnect { - + /// @brief MTConnect validation containers namespace validation { - + /// @brief Observation validation containers namespace observations { - + /// @brief Validation type for observations using Validation = std::unordered_map>; From 5ea60241d148caf843764e2b516af74a246044ba Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 18 Apr 2024 22:36:26 -0400 Subject: [PATCH 080/128] Handled threading issues and send queue --- src/mtconnect/observation/change_observer.cpp | 4 + src/mtconnect/sink/rest_sink/rest_service.cpp | 28 ++- src/mtconnect/sink/rest_sink/rest_service.hpp | 6 +- src/mtconnect/sink/rest_sink/session.hpp | 5 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 4 +- src/mtconnect/sink/rest_sink/session_impl.hpp | 5 +- .../sink/rest_sink/websocket_session.hpp | 209 ++++++++++++++---- 7 files changed, 206 insertions(+), 55 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index 88b5c5da4..dde38e9a3 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -145,9 +145,12 @@ namespace mtconnect::observation { void AsyncObserver::handlerCompleted() { + NAMED_SCOPE("AsyncObserver::handlerCompleted"); + m_last = std::chrono::system_clock::now(); if (m_endOfBuffer) { + LOG(trace) << "End of buffer"; using std::placeholders::_1; m_observer.waitForSignal(m_heartbeat); } @@ -159,6 +162,7 @@ namespace mtconnect::observation { void AsyncObserver::handleSignal(boost::system::error_code ec) { + NAMED_SCOPE("AsyncObserver::handleSignal"); using namespace buffer; using std::placeholders::_1; diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 83401420e..2c5a5c04a 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -672,7 +672,8 @@ namespace mtconnect { streamCurrentRequest( session, printerForAccepts(request->m_accepts), *interval, request->parameter("device"), request->parameter("path"), - *request->parameter("pretty"), request->parameter("deviceType")); + *request->parameter("pretty"), request->parameter("deviceType"), + request->m_requestId); } else { @@ -714,7 +715,8 @@ namespace mtconnect { *request->parameter("heartbeat"), *request->parameter("count"), request->parameter("device"), request->parameter("from"), request->parameter("path"), *request->parameter("pretty"), - request->parameter("deviceType")); + request->parameter("deviceType"), + request->m_requestId); } else { @@ -935,6 +937,7 @@ namespace mtconnect { rest_sink::SessionPtr m_session; ofstream m_log; bool m_pretty {false}; + std::optional m_requestId; }; void RestService::streamSampleRequest(rest_sink::SessionPtr session, const Printer *printer, @@ -942,7 +945,8 @@ namespace mtconnect { const int count, const std::optional &device, const std::optional &from, const std::optional &path, bool pretty, - const std::optional &deviceType) + const std::optional &deviceType, + const std::optional &requestId) { NAMED_SCOPE("RestService::streamSampleRequest"); @@ -976,6 +980,7 @@ namespace mtconnect { asyncResponse->m_printer = printer; asyncResponse->m_sink = getptr(); asyncResponse->m_pretty = pretty; + asyncResponse->m_requestId = requestId; if (m_logStreamData) { @@ -993,7 +998,8 @@ namespace mtconnect { session->beginStreaming( printer->mimeType(), asio::bind_executor(m_strand, - boost::bind(&AsyncObserver::handlerCompleted, asyncResponse))); + boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), + requestId); } SequenceNumber_t RestService::streamNextSampleChunk( @@ -1024,7 +1030,9 @@ namespace mtconnect { asyncResponse->m_session->writeChunk( content, asio::bind_executor( - m_strand, boost::bind(&AsyncObserver::handlerCompleted, asyncResponse))); + m_strand, boost::bind(&AsyncObserver::handlerCompleted, asyncResponse) + ), + asyncResponse->m_requestId); return end; } @@ -1062,13 +1070,15 @@ namespace mtconnect { FilterSetOpt m_filter; boost::asio::steady_timer m_timer; bool m_pretty {false}; + std::optional m_requestId; }; void RestService::streamCurrentRequest(SessionPtr session, const Printer *printer, const int interval, const std::optional &device, const std::optional &path, bool pretty, - const std::optional &deviceType) + const std::optional &deviceType, + const std::optional &requestId) { checkRange(printer, interval, 0, numeric_limits().max(), "interval"); DevicePtr dev {nullptr}; @@ -1087,11 +1097,13 @@ namespace mtconnect { asyncResponse->m_printer = printer; asyncResponse->m_service = getptr(); asyncResponse->m_pretty = pretty; + asyncResponse->m_requestId = requestId; asyncResponse->m_session->beginStreaming( printer->mimeType(), boost::asio::bind_executor(m_strand, [this, asyncResponse]() { streamNextCurrent(asyncResponse, boost::system::error_code {}); - })); + }), + requestId); } void RestService::streamNextCurrent(std::shared_ptr asyncResponse, @@ -1130,7 +1142,7 @@ namespace mtconnect { asyncResponse->m_timer.expires_from_now(asyncResponse->m_interval); asyncResponse->m_timer.async_wait(boost::asio::bind_executor( m_strand, boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); - })); + }), asyncResponse->m_requestId); } catch (RequestError &re) { diff --git a/src/mtconnect/sink/rest_sink/rest_service.hpp b/src/mtconnect/sink/rest_sink/rest_service.hpp index 923f210df..934231443 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.hpp +++ b/src/mtconnect/sink/rest_sink/rest_service.hpp @@ -149,7 +149,8 @@ namespace mtconnect { const std::optional &from = std::nullopt, const std::optional &path = std::nullopt, bool pretty = false, - const std::optional &deviceType = std::nullopt); + const std::optional &deviceType = std::nullopt, + const std::optional &responseId = std::nullopt); /// @brief Handler for a streaming current /// @param[in] session session to stream data to @@ -162,7 +163,8 @@ namespace mtconnect { const std::optional &device = std::nullopt, const std::optional &path = std::nullopt, bool pretty = false, - const std::optional &deviceType = std::nullopt); + const std::optional &deviceType = std::nullopt, + const std::optional &responseId = std::nullopt); /// @brief Handler for put/post observation /// @param[in] p printer for response generation /// @param[in] device device diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index c4ed9041a..dcb30e911 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -64,11 +64,12 @@ namespace mtconnect::sink::rest_sink { /// @brief begin streaming data to the client using x-multipart-replace /// @param mimeType the mime type of the response /// @param complete completion callback - virtual void beginStreaming(const std::string &mimeType, Complete complete) = 0; + virtual void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) = 0; /// @brief write a chunk for a streaming session /// @param chunk the chunk to write /// @param complete a completion callback - virtual void writeChunk(const std::string &chunk, Complete complete) = 0; + virtual void writeChunk(const std::string &chunk, Complete complete, + std::optional requestId = std::nullopt) = 0; /// @brief close the session virtual void close() = 0; /// @brief close the stream diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index d84c43fd7..cce9a9881 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -287,7 +287,7 @@ namespace mtconnect::sink::rest_sink { } template - void SessionImpl::beginStreaming(const std::string &mimeType, Complete complete) + void SessionImpl::beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId) { NAMED_SCOPE("SessionImpl::beginStreaming"); @@ -321,7 +321,7 @@ namespace mtconnect::sink::rest_sink { } template - void SessionImpl::writeChunk(const std::string &body, Complete complete) + void SessionImpl::writeChunk(const std::string &body, Complete complete, std::optional requestId) { NAMED_SCOPE("SessionImpl::writeChunk"); diff --git a/src/mtconnect/sink/rest_sink/session_impl.hpp b/src/mtconnect/sink/rest_sink/session_impl.hpp index 07ab7fbd0..2c046171a 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.hpp +++ b/src/mtconnect/sink/rest_sink/session_impl.hpp @@ -74,8 +74,9 @@ namespace mtconnect { void run() override; void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override; void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override; - void beginStreaming(const std::string &mimeType, Complete complete) override; - void writeChunk(const std::string &chunk, Complete complete) override; + void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) override; + void writeChunk(const std::string &chunk, Complete complete, + std::optional requestId = std::nullopt) override; void closeStream() override; ///@} protected: diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index f39b559e5..c580facf3 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,8 @@ namespace mtconnect::sink::rest_sink { struct WebsocketRequest { + WebsocketRequest(const std::string &id) + : m_requestId(id) { } std::string m_requestId; std::optional m_streamBuffer; Complete m_complete; @@ -46,6 +49,19 @@ namespace mtconnect::sink::rest_sink { template class WebsocketSession : public Session { + protected: + struct Message { + Message(const std::string &body, Complete &complete, + const std::string &requestId) + : m_body(body), m_complete(complete), m_requestId(requestId) + { + } + + std::string m_body; + Complete m_complete; + std::string m_requestId; + }; + public: using RequestMessage = boost::beast::http::request; @@ -69,7 +85,7 @@ namespace mtconnect::sink::rest_sink { // Set suggested timeout settings for the websocket derived().stream().set_option( websocket::stream_base::timeout::suggested(beast::role_type::server)); - + // Set a decorator to change the Server of the handshake derived().stream().set_option( websocket::stream_base::decorator([](websocket::response_type &res) { @@ -78,51 +94,78 @@ namespace mtconnect::sink::rest_sink { // Accept the websocket handshake derived().stream().async_accept( - m_msg, beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr())); + m_msg, boost::asio::bind_executor(derived().getExecutor(), beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr()))); } void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { - if (response->m_requestId) + NAMED_SCOPE("WebsocketSession::writeResponse"); + if (!response->m_requestId) { - auto id = *(response->m_requestId); + boost::system::error_code ec; + return fail(status::bad_request, "Missing request Id", ec); + } + + writeChunk(response->m_body, complete, response->m_requestId); + } + + void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override + { + NAMED_SCOPE("WebsocketSession::writeFailureResponse"); + writeChunk(response->m_body, complete, response->m_requestId); + } + + void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) override + { + if (requestId) + { + auto id = *(requestId); auto it = m_requests.find(id); if (it != m_requests.end()) { - using namespace std::placeholders; - auto &req = it->second; - req.m_complete = complete; - req.m_streamBuffer.emplace(); - std::ostream str(&req.m_streamBuffer.value()); - - str << response->m_body; - - derived().stream().text(derived().stream().got_text()); - derived().stream().async_write( - req.m_streamBuffer->data(), - beast::bind_handler( - [this, id](beast::error_code ec, std::size_t len) { sent(ec, len, id); }, _1, - _2)); + req.m_streaming = true; + + if (complete) + complete(); } else { - LOG(error) << "WebsocketSession::writeResponse: Cannot find request for id: " << id; + LOG(error) << "Cannot find request for id: " << id; } } else { - LOG(error) << "WebsocketSession::writeResponse: No request id for websocket"; + LOG(error) << "No request id for websocket"; } } - void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override {} - - void beginStreaming(const std::string &mimeType, Complete complete) override {} - - void writeChunk(const std::string &chunk, Complete complete) override {} + void writeChunk(const std::string &chunk, Complete complete, std::optional requestId = std::nullopt) override + { + NAMED_SCOPE("WebsocketSession::writeChunk"); + if (requestId) + { + LOG(trace) << "Waiting for mutex"; + std::lock_guard lock(m_mutex); + + if (m_busy) + { + m_messageQueue.emplace_back(chunk, complete, *requestId); + } + else + { + send(chunk, complete, *requestId); + } + } + else + { + LOG(error) << "No request id for websocket"; + } + } - void closeStream() override {} + void closeStream() override + { + } protected: void onAccept(boost::beast::error_code ec) @@ -136,31 +179,101 @@ namespace mtconnect::sink::rest_sink { derived().stream().async_read( m_buffer, beast::bind_front_handler(&WebsocketSession::onRead, derived().shared_ptr())); } - - void sent(beast::error_code ec, std::size_t len, const std::string &id) + + void send(const std::string body, Complete complete, const std::string &requestId) { - auto it = m_requests.find(id); + NAMED_SCOPE("WebsocketSession::send"); + + using namespace std::placeholders; + + auto it = m_requests.find(requestId); if (it != m_requests.end()) { auto &req = it->second; - if (req.m_complete) + req.m_complete = complete; + req.m_streamBuffer.emplace(); + std::ostream str(&req.m_streamBuffer.value()); + + str << body; + + auto ref = derived().shared_ptr(); + + LOG(trace) << "writing chunk for ws: " << requestId; + + m_busy = true; + + derived().stream().text(derived().stream().got_text()); + derived().stream().async_write( + req.m_streamBuffer->data(), + beast::bind_handler( + [ref, requestId](beast::error_code ec, std::size_t len) { ref->sent(ec, len, requestId); }, _1, + _2)); + } + else + { + LOG(error) << "Cannot find request for id: " << requestId; + } + } + + void sent(beast::error_code ec, std::size_t len, const std::string &id) + { + NAMED_SCOPE("WebsocketSession::sent"); + + if (ec) + { + return fail(status::bad_request, "Missing request Id", ec); + } + + { + LOG(trace) << "Waiting for mutex"; + std::lock_guard lock(m_mutex); + + LOG(trace) << "sent chunk for ws: " << id; + + auto it = m_requests.find(id); + if (it != m_requests.end()) { - req.m_complete(); + auto &req = it->second; + if (req.m_complete) + { + boost::asio::post(derived().stream().get_executor(), + req.m_complete); + } + + if (!req.m_streaming) + { + m_requests.erase(id); + } + + if (m_messageQueue.size() == 0) + { + m_busy = false; + } } - - if (!req.m_streaming) + else { - m_requests.erase(id); + LOG(error) << "WebsocketSession::sent: Cannot find request for id: " << id; } } - else + { - LOG(error) << "WebsocketSession::sent: Cannot find request for id: " << id; + LOG(trace) << "Waiting for mutex to send next"; + std::lock_guard lock(m_mutex); + + // Check for queued messages + if (m_messageQueue.size() > 0) + { + auto &msg = m_messageQueue.front(); + send(msg.m_body, msg.m_complete, msg.m_requestId); + m_messageQueue.pop_front(); + } } } void onRead(beast::error_code ec, std::size_t len) { + NAMED_SCOPE("PlainWebsocketSession::onRead"); + if (ec) return fail(boost::beast::http::status::internal_server_error, "shutdown", ec); @@ -252,9 +365,16 @@ namespace mtconnect::sink::rest_sink { m_request->m_parameters.erase("id"); } - auto &req = m_requests[*(m_request->m_requestId)]; - req.m_requestId = *(m_request->m_requestId); - + auto &id = *(m_request->m_requestId); + + auto res = m_requests.emplace(id, id); + if (!res.second) + { + LOG(error) << "Duplicate request id: " << id; + boost::system::error_code ec; + return fail(status::bad_request, "Duplicate request Id", ec); + } + if (!m_dispatch(derived().shared_ptr(), m_request)) { ostringstream txt; @@ -272,6 +392,9 @@ namespace mtconnect::sink::rest_sink { RequestMessage m_msg; beast::flat_buffer m_buffer; std::map m_requests; + std::mutex m_mutex; + std::atomic_bool m_busy; + std::deque m_messageQueue; }; template @@ -297,6 +420,10 @@ namespace mtconnect::sink::rest_sink { if (m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } + + auto getExecutor() { + return m_stream.get_executor(); + } auto &stream() { return m_stream; } @@ -324,6 +451,10 @@ namespace mtconnect::sink::rest_sink { ~TlsWebsocketSession() { close(); } auto &stream() { return m_stream; } + + auto getExecutor() { + return m_stream.get_executor(); + } void close() override { From c1e0774c15e9906cba7f79d65ed31731773cf719 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 18 Apr 2024 22:51:13 -0400 Subject: [PATCH 081/128] fixed expiry timeout --- src/mtconnect/sink/rest_sink/websocket_session.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index c580facf3..11bea0441 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -409,7 +409,9 @@ namespace mtconnect::sink::rest_sink { Dispatch dispatch, ErrorFunction func) : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) - {} + { + beast::get_lowest_layer(m_stream).expires_never(); + } ~PlainWebsocketSession() { close(); } void close() override @@ -447,7 +449,9 @@ namespace mtconnect::sink::rest_sink { RequestMessage &&msg, Dispatch dispatch, ErrorFunction func) : WebsocketSession(std::move(request), std::move(msg), dispatch, func), m_stream(std::move(stream)) - {} + { + beast::get_lowest_layer(m_stream).expires_never(); + } ~TlsWebsocketSession() { close(); } auto &stream() { return m_stream; } From 18ff96a00a53a9a6bdb261840522b6226327d138 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 18 Apr 2024 22:53:46 -0400 Subject: [PATCH 082/128] Formatted new code --- src/mtconnect/observation/change_observer.cpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 48 +++++---- src/mtconnect/sink/rest_sink/session.hpp | 3 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 6 +- src/mtconnect/sink/rest_sink/session_impl.hpp | 3 +- .../sink/rest_sink/websocket_session.hpp | 100 +++++++++--------- 6 files changed, 84 insertions(+), 78 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index dde38e9a3..e186a592b 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -146,7 +146,7 @@ namespace mtconnect::observation { void AsyncObserver::handlerCompleted() { NAMED_SCOPE("AsyncObserver::handlerCompleted"); - + m_last = std::chrono::system_clock::now(); if (m_endOfBuffer) { diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 2c5a5c04a..ebc531878 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -669,11 +669,11 @@ namespace mtconnect { auto interval = request->parameter("interval"); if (interval) { - streamCurrentRequest( - session, printerForAccepts(request->m_accepts), *interval, - request->parameter("device"), request->parameter("path"), - *request->parameter("pretty"), request->parameter("deviceType"), - request->m_requestId); + streamCurrentRequest(session, printerForAccepts(request->m_accepts), *interval, + request->parameter("device"), + request->parameter("path"), + *request->parameter("pretty"), + request->parameter("deviceType"), request->m_requestId); } else { @@ -715,8 +715,7 @@ namespace mtconnect { *request->parameter("heartbeat"), *request->parameter("count"), request->parameter("device"), request->parameter("from"), request->parameter("path"), *request->parameter("pretty"), - request->parameter("deviceType"), - request->m_requestId); + request->parameter("deviceType"), request->m_requestId); } else { @@ -999,7 +998,7 @@ namespace mtconnect { printer->mimeType(), asio::bind_executor(m_strand, boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), - requestId); + requestId); } SequenceNumber_t RestService::streamNextSampleChunk( @@ -1029,10 +1028,10 @@ namespace mtconnect { asyncResponse->m_log << content << endl; asyncResponse->m_session->writeChunk( - content, asio::bind_executor( - m_strand, boost::bind(&AsyncObserver::handlerCompleted, asyncResponse) - ), - asyncResponse->m_requestId); + content, + asio::bind_executor(m_strand, + boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), + asyncResponse->m_requestId); return end; } @@ -1100,10 +1099,13 @@ namespace mtconnect { asyncResponse->m_requestId = requestId; asyncResponse->m_session->beginStreaming( - printer->mimeType(), boost::asio::bind_executor(m_strand, [this, asyncResponse]() { - streamNextCurrent(asyncResponse, boost::system::error_code {}); - }), - requestId); + printer->mimeType(), + boost::asio::bind_executor(m_strand, + [this, asyncResponse]() { + streamNextCurrent(asyncResponse, + boost::system::error_code {}); + }), + requestId); } void RestService::streamNextCurrent(std::shared_ptr asyncResponse, @@ -1138,11 +1140,15 @@ namespace mtconnect { asyncResponse->m_session->writeChunk( fetchCurrentData(asyncResponse->m_printer, asyncResponse->m_filter, nullopt, asyncResponse->m_pretty), - boost::asio::bind_executor(m_strand, [this, asyncResponse]() { - asyncResponse->m_timer.expires_from_now(asyncResponse->m_interval); - asyncResponse->m_timer.async_wait(boost::asio::bind_executor( - m_strand, boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); - }), asyncResponse->m_requestId); + boost::asio::bind_executor( + m_strand, + [this, asyncResponse]() { + asyncResponse->m_timer.expires_from_now(asyncResponse->m_interval); + asyncResponse->m_timer.async_wait(boost::asio::bind_executor( + m_strand, + boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); + }), + asyncResponse->m_requestId); } catch (RequestError &re) { diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index dcb30e911..4e2bc52ab 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -64,7 +64,8 @@ namespace mtconnect::sink::rest_sink { /// @brief begin streaming data to the client using x-multipart-replace /// @param mimeType the mime type of the response /// @param complete completion callback - virtual void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) = 0; + virtual void beginStreaming(const std::string &mimeType, Complete complete, + std::optional requestId = std::nullopt) = 0; /// @brief write a chunk for a streaming session /// @param chunk the chunk to write /// @param complete a completion callback diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index cce9a9881..40777da00 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -287,7 +287,8 @@ namespace mtconnect::sink::rest_sink { } template - void SessionImpl::beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId) + void SessionImpl::beginStreaming(const std::string &mimeType, Complete complete, + std::optional requestId) { NAMED_SCOPE("SessionImpl::beginStreaming"); @@ -321,7 +322,8 @@ namespace mtconnect::sink::rest_sink { } template - void SessionImpl::writeChunk(const std::string &body, Complete complete, std::optional requestId) + void SessionImpl::writeChunk(const std::string &body, Complete complete, + std::optional requestId) { NAMED_SCOPE("SessionImpl::writeChunk"); diff --git a/src/mtconnect/sink/rest_sink/session_impl.hpp b/src/mtconnect/sink/rest_sink/session_impl.hpp index 2c046171a..b890a6039 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.hpp +++ b/src/mtconnect/sink/rest_sink/session_impl.hpp @@ -74,7 +74,8 @@ namespace mtconnect { void run() override; void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override; void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override; - void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) override; + void beginStreaming(const std::string &mimeType, Complete complete, + std::optional requestId = std::nullopt) override; void writeChunk(const std::string &chunk, Complete complete, std::optional requestId = std::nullopt) override; void closeStream() override; diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 11bea0441..bd7d321fe 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -22,8 +22,8 @@ #include #include -#include #include +#include #include #include @@ -37,8 +37,7 @@ namespace mtconnect::sink::rest_sink { struct WebsocketRequest { - WebsocketRequest(const std::string &id) - : m_requestId(id) { } + WebsocketRequest(const std::string &id) : m_requestId(id) {} std::string m_requestId; std::optional m_streamBuffer; Complete m_complete; @@ -50,18 +49,17 @@ namespace mtconnect::sink::rest_sink { class WebsocketSession : public Session { protected: - struct Message { - Message(const std::string &body, Complete &complete, - const std::string &requestId) - : m_body(body), m_complete(complete), m_requestId(requestId) - { - } - + struct Message + { + Message(const std::string &body, Complete &complete, const std::string &requestId) + : m_body(body), m_complete(complete), m_requestId(requestId) + {} + std::string m_body; Complete m_complete; std::string m_requestId; }; - + public: using RequestMessage = boost::beast::http::request; @@ -85,7 +83,7 @@ namespace mtconnect::sink::rest_sink { // Set suggested timeout settings for the websocket derived().stream().set_option( websocket::stream_base::timeout::suggested(beast::role_type::server)); - + // Set a decorator to change the Server of the handshake derived().stream().set_option( websocket::stream_base::decorator([](websocket::response_type &res) { @@ -94,7 +92,9 @@ namespace mtconnect::sink::rest_sink { // Accept the websocket handshake derived().stream().async_accept( - m_msg, boost::asio::bind_executor(derived().getExecutor(), beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr()))); + m_msg, boost::asio::bind_executor(derived().getExecutor(), + beast::bind_front_handler(&WebsocketSession::onAccept, + derived().shared_ptr()))); } void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override @@ -109,13 +109,14 @@ namespace mtconnect::sink::rest_sink { writeChunk(response->m_body, complete, response->m_requestId); } - void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override + void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override { NAMED_SCOPE("WebsocketSession::writeFailureResponse"); writeChunk(response->m_body, complete, response->m_requestId); } - void beginStreaming(const std::string &mimeType, Complete complete, std::optional requestId = std::nullopt) override + void beginStreaming(const std::string &mimeType, Complete complete, + std::optional requestId = std::nullopt) override { if (requestId) { @@ -125,7 +126,7 @@ namespace mtconnect::sink::rest_sink { { auto &req = it->second; req.m_streaming = true; - + if (complete) complete(); } @@ -140,14 +141,15 @@ namespace mtconnect::sink::rest_sink { } } - void writeChunk(const std::string &chunk, Complete complete, std::optional requestId = std::nullopt) override + void writeChunk(const std::string &chunk, Complete complete, + std::optional requestId = std::nullopt) override { NAMED_SCOPE("WebsocketSession::writeChunk"); if (requestId) { LOG(trace) << "Waiting for mutex"; std::lock_guard lock(m_mutex); - + if (m_busy) { m_messageQueue.emplace_back(chunk, complete, *requestId); @@ -163,9 +165,7 @@ namespace mtconnect::sink::rest_sink { } } - void closeStream() override - { - } + void closeStream() override {} protected: void onAccept(boost::beast::error_code ec) @@ -179,13 +179,13 @@ namespace mtconnect::sink::rest_sink { derived().stream().async_read( m_buffer, beast::bind_front_handler(&WebsocketSession::onRead, derived().shared_ptr())); } - + void send(const std::string body, Complete complete, const std::string &requestId) { NAMED_SCOPE("WebsocketSession::send"); using namespace std::placeholders; - + auto it = m_requests.find(requestId); if (it != m_requests.end()) { @@ -193,21 +193,22 @@ namespace mtconnect::sink::rest_sink { req.m_complete = complete; req.m_streamBuffer.emplace(); std::ostream str(&req.m_streamBuffer.value()); - + str << body; - + auto ref = derived().shared_ptr(); - + LOG(trace) << "writing chunk for ws: " << requestId; - + m_busy = true; - + derived().stream().text(derived().stream().got_text()); - derived().stream().async_write( - req.m_streamBuffer->data(), + derived().stream().async_write(req.m_streamBuffer->data(), beast::bind_handler( - [ref, requestId](beast::error_code ec, std::size_t len) { ref->sent(ec, len, requestId); }, _1, - _2)); + [ref, requestId](beast::error_code ec, std::size_t len) { + ref->sent(ec, len, requestId); + }, + _1, _2)); } else { @@ -218,33 +219,32 @@ namespace mtconnect::sink::rest_sink { void sent(beast::error_code ec, std::size_t len, const std::string &id) { NAMED_SCOPE("WebsocketSession::sent"); - + if (ec) { return fail(status::bad_request, "Missing request Id", ec); } - + { LOG(trace) << "Waiting for mutex"; std::lock_guard lock(m_mutex); LOG(trace) << "sent chunk for ws: " << id; - + auto it = m_requests.find(id); if (it != m_requests.end()) { auto &req = it->second; if (req.m_complete) { - boost::asio::post(derived().stream().get_executor(), - req.m_complete); + boost::asio::post(derived().stream().get_executor(), req.m_complete); } - + if (!req.m_streaming) { m_requests.erase(id); } - + if (m_messageQueue.size() == 0) { m_busy = false; @@ -255,11 +255,11 @@ namespace mtconnect::sink::rest_sink { LOG(error) << "WebsocketSession::sent: Cannot find request for id: " << id; } } - + { LOG(trace) << "Waiting for mutex to send next"; std::lock_guard lock(m_mutex); - + // Check for queued messages if (m_messageQueue.size() > 0) { @@ -273,7 +273,7 @@ namespace mtconnect::sink::rest_sink { void onRead(beast::error_code ec, std::size_t len) { NAMED_SCOPE("PlainWebsocketSession::onRead"); - + if (ec) return fail(boost::beast::http::status::internal_server_error, "shutdown", ec); @@ -366,7 +366,7 @@ namespace mtconnect::sink::rest_sink { } auto &id = *(m_request->m_requestId); - + auto res = m_requests.emplace(id, id); if (!res.second) { @@ -374,7 +374,7 @@ namespace mtconnect::sink::rest_sink { boost::system::error_code ec; return fail(status::bad_request, "Duplicate request Id", ec); } - + if (!m_dispatch(derived().shared_ptr(), m_request)) { ostringstream txt; @@ -422,10 +422,8 @@ namespace mtconnect::sink::rest_sink { if (m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } - - auto getExecutor() { - return m_stream.get_executor(); - } + + auto getExecutor() { return m_stream.get_executor(); } auto &stream() { return m_stream; } @@ -455,10 +453,8 @@ namespace mtconnect::sink::rest_sink { ~TlsWebsocketSession() { close(); } auto &stream() { return m_stream; } - - auto getExecutor() { - return m_stream.get_executor(); - } + + auto getExecutor() { return m_stream.get_executor(); } void close() override { From c1c4b8d5f36d3ce34d45ac8bd5e1c0575af9b232 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 19 Apr 2024 11:13:26 -0400 Subject: [PATCH 083/128] Working version with error handling --- .../sink/rest_sink/websocket_session.hpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index bd7d321fe..fcf91939e 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -150,7 +150,7 @@ namespace mtconnect::sink::rest_sink { LOG(trace) << "Waiting for mutex"; std::lock_guard lock(m_mutex); - if (m_busy) + if (m_busy || m_messageQueue.size() > 0) { m_messageQueue.emplace_back(chunk, complete, *requestId); } @@ -165,8 +165,6 @@ namespace mtconnect::sink::rest_sink { } } - void closeStream() override {} - protected: void onAccept(boost::beast::error_code ec) { @@ -372,7 +370,7 @@ namespace mtconnect::sink::rest_sink { { LOG(error) << "Duplicate request id: " << id; boost::system::error_code ec; - return fail(status::bad_request, "Duplicate request Id", ec); + fail(status::bad_request, "Duplicate request Id", ec); } if (!m_dispatch(derived().shared_ptr(), m_request)) @@ -380,6 +378,8 @@ namespace mtconnect::sink::rest_sink { ostringstream txt; txt << "Failed to find handler for " << buffer; LOG(error) << txt.str(); + boost::system::error_code ec; + fail(status::bad_request, "Duplicate request Id", ec); } } @@ -419,10 +419,16 @@ namespace mtconnect::sink::rest_sink { NAMED_SCOPE("PlainWebsocketSession::close"); m_request.reset(); + closeStream(); + } + + void closeStream() override + { if (m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } + auto getExecutor() { return m_stream.get_executor(); } auto &stream() { return m_stream; } @@ -461,6 +467,11 @@ namespace mtconnect::sink::rest_sink { NAMED_SCOPE("TlsWebsocketSession::close"); m_request.reset(); + closeStream(); + } + + void closeStream() override + { if (m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } From 4fc1d7a4a9db0f4aed2e74b2791d09c24d975dc3 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 19 Apr 2024 11:36:37 -0400 Subject: [PATCH 084/128] Added request id to the printers for XML --- src/mtconnect/printer/json_printer.cpp | 12 +++-- src/mtconnect/printer/json_printer.hpp | 12 +++-- src/mtconnect/printer/printer.hpp | 15 ++++--- src/mtconnect/printer/xml_printer.cpp | 27 ++++++++---- src/mtconnect/printer/xml_printer.hpp | 13 +++--- src/mtconnect/sink/rest_sink/rest_service.cpp | 44 ++++++++++++------- src/mtconnect/sink/rest_sink/rest_service.hpp | 28 +++++++----- 7 files changed, 98 insertions(+), 53 deletions(-) diff --git a/src/mtconnect/printer/json_printer.cpp b/src/mtconnect/printer/json_printer.cpp index 287203797..c604a6536 100644 --- a/src/mtconnect/printer/json_printer.cpp +++ b/src/mtconnect/printer/json_printer.cpp @@ -113,7 +113,8 @@ namespace mtconnect::printer { std::string JsonPrinter::printErrors(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty) const + bool pretty, + const std::optional requestId) const { defaultSchemaVersion(); @@ -170,7 +171,8 @@ namespace mtconnect::printer { const unsigned int assetCount, const std::list &devices, const std::map *count, - bool includeHidden, bool pretty) const + bool includeHidden, bool pretty, + const std::optional requestId) const { defaultSchemaVersion(); @@ -197,7 +199,8 @@ namespace mtconnect::printer { std::string JsonPrinter::printAssets(const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetCount, const asset::AssetList &asset, - bool pretty) const + bool pretty, + const std::optional requestId) const { defaultSchemaVersion(); @@ -397,7 +400,8 @@ namespace mtconnect::printer { std::string JsonPrinter::printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, ObservationList &observations, - bool pretty) const + bool pretty, + const std::optional requestId) const { defaultSchemaVersion(); diff --git a/src/mtconnect/printer/json_printer.hpp b/src/mtconnect/printer/json_printer.hpp index fd392133a..102cf51ec 100644 --- a/src/mtconnect/printer/json_printer.hpp +++ b/src/mtconnect/printer/json_printer.hpp @@ -32,21 +32,25 @@ namespace mtconnect::printer { std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false) const override; + bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string printProbe(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const unsigned int assetBufferSize, const unsigned int assetCount, const std::list &devices, const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false) const override; + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, - bool pretty = false) const override; + bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, const asset::AssetList &asset, - bool pretty = false) const override; + bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string mimeType() const override { return "application/mtconnect+json"; } uint32_t getJsonVersion() const { return m_jsonVersion; } diff --git a/src/mtconnect/printer/printer.hpp b/src/mtconnect/printer/printer.hpp index 52943c175..38727109f 100644 --- a/src/mtconnect/printer/printer.hpp +++ b/src/mtconnect/printer/printer.hpp @@ -63,7 +63,8 @@ namespace mtconnect { /// @return the error document virtual std::string printError(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const std::string &errorCode, - const std::string &errorText, bool pretty = false) const + const std::string &errorText, bool pretty = false, + const std::optional requestId = std::nullopt) const { return printErrors(instanceId, bufferSize, nextSeq, {{errorCode, errorText}}); } @@ -75,7 +76,8 @@ namespace mtconnect { /// @return the MTConnect Error document virtual std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false) const = 0; + bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief Generate an MTConnect Devices document /// @param[in] instanceId the instance id /// @param[in] bufferSize the buffer size @@ -90,7 +92,8 @@ namespace mtconnect { const unsigned int assetCount, const std::list &devices, const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false) const = 0; + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief Print a MTConnect Streams document /// @param[in] instanceId the instance id /// @param[in] bufferSize the buffer size @@ -102,7 +105,8 @@ namespace mtconnect { virtual std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, - bool pretty = false) const = 0; + bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief Generate an MTConnect Assets document /// @param[in] anInstanceId the instance id /// @param[in] bufferSize the buffer size @@ -111,7 +115,8 @@ namespace mtconnect { /// @return the MTConnect Assets document virtual std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, asset::AssetList const &asset, - bool pretty = false) const = 0; + bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief get the mime type for the documents /// @return the mime type virtual std::string mimeType() const = 0; diff --git a/src/mtconnect/printer/xml_printer.cpp b/src/mtconnect/printer/xml_printer.cpp index 1c155e98b..75232f818 100644 --- a/src/mtconnect/printer/xml_printer.cpp +++ b/src/mtconnect/printer/xml_printer.cpp @@ -344,7 +344,7 @@ namespace mtconnect::printer { std::string XmlPrinter::printErrors(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty) const + bool pretty, const std::optional requestId) const { string ret; @@ -352,7 +352,8 @@ namespace mtconnect::printer { { XmlWriter writer(m_pretty || pretty); - initXmlDoc(writer, eERROR, instanceId, bufferSize, 0, 0, nextSeq, nextSeq - 1); + initXmlDoc(writer, eERROR, instanceId, bufferSize, 0, 0, nextSeq, 0, nextSeq - 1, + nullptr, requestId); { AutoElement e1(writer, "Errors"); @@ -382,7 +383,7 @@ namespace mtconnect::printer { const uint64_t nextSeq, const unsigned int assetBufferSize, const unsigned int assetCount, const list &deviceList, const std::map *count, bool includeHidden, - bool pretty) const + bool pretty, const std::optional requestId) const { string ret; @@ -391,7 +392,7 @@ namespace mtconnect::printer { XmlWriter writer(m_pretty || pretty); initXmlDoc(writer, eDEVICES, instanceId, bufferSize, assetBufferSize, assetCount, nextSeq, 0, - nextSeq - 1, count); + nextSeq - 1, count, requestId); { AutoElement devices(writer, "Devices"); @@ -443,7 +444,7 @@ namespace mtconnect::printer { string XmlPrinter::printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, ObservationList &observations, - bool pretty) const + bool pretty, const std::optional requestId) const { string ret; @@ -451,7 +452,8 @@ namespace mtconnect::printer { { XmlWriter writer(m_pretty || pretty); - initXmlDoc(writer, eSTREAMS, instanceId, bufferSize, 0, 0, nextSeq, firstSeq, lastSeq); + initXmlDoc(writer, eSTREAMS, instanceId, bufferSize, 0, 0, nextSeq, firstSeq, lastSeq, + nullptr, requestId); AutoElement streams(writer, "Streams"); @@ -523,13 +525,15 @@ namespace mtconnect::printer { string XmlPrinter::printAssets(const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetCount, const AssetList &asset, - bool pretty) const + bool pretty, + const std::optional requestId) const { string ret; try { XmlWriter writer(m_pretty || pretty); - initXmlDoc(writer, eASSETS, instanceId, 0u, bufferSize, assetCount, 0ull); + initXmlDoc(writer, eASSETS, instanceId, 0u, bufferSize, assetCount, 0ull, + 0, 0, nullptr, requestId); { AutoElement ele(writer, "Assets"); @@ -565,7 +569,8 @@ namespace mtconnect::printer { const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetBufferSize, const unsigned int assetCount, const uint64_t nextSeq, const uint64_t firstSeq, - const uint64_t lastSeq, const map *count) const + const uint64_t lastSeq, const map *count, + const std::optional requestId) const { THROW_IF_XML2_ERROR(xmlTextWriterStartDocument(writer, nullptr, "UTF-8", nullptr)); @@ -671,6 +676,10 @@ namespace mtconnect::printer { sprintf(version, "%d.%d.%d.%d", AGENT_VERSION_MAJOR, AGENT_VERSION_MINOR, AGENT_VERSION_PATCH, AGENT_VERSION_BUILD); addAttribute(writer, "version", version); + + if (requestId) + addAttribute(writer, "requestId", *requestId); + int major, minor; char c; diff --git a/src/mtconnect/printer/xml_printer.hpp b/src/mtconnect/printer/xml_printer.hpp index f1f6910f9..71a2ef90e 100644 --- a/src/mtconnect/printer/xml_printer.hpp +++ b/src/mtconnect/printer/xml_printer.hpp @@ -45,21 +45,23 @@ namespace mtconnect { std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false) const override; + bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string printProbe(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const unsigned int assetBufferSize, const unsigned int assetCount, const std::list &devices, const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false) const override; + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, - bool pretty = false) const override; + bool pretty = false, const std::optional requestId = std::nullopt) const override; std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, const asset::AssetList &asset, - bool pretty = false) const override; + bool pretty = false, const std::optional requestId = std::nullopt) const override; std::string mimeType() const override { return "text/xml"; } /// @brief Print a single device in XML @@ -172,7 +174,8 @@ namespace mtconnect { const unsigned int bufferSize, const unsigned int assetBufferSize, const unsigned int assetCount, const uint64_t nextSeq, const uint64_t firstSeq = 0, const uint64_t lastSeq = 0, - const std::map *counts = nullptr) const; + const std::map *counts = nullptr, + const std::optional requestId = std::nullopt) const; // Helper to print individual components and details void printProbeHelper(xmlTextWriterPtr writer, device_model::ComponentPtr component, diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index ebc531878..0f585e8b2 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -798,7 +798,8 @@ namespace mtconnect { ResponsePtr RestService::probeRequest(const Printer *printer, const std::optional &device, bool pretty, - const std::optional &deviceType) + const std::optional &deviceType, + const std::optional &requestId) { NAMED_SCOPE("RestService::probeRequest"); @@ -835,7 +836,8 @@ namespace mtconnect { const std::optional &device, const std::optional &at, const std::optional &path, bool pretty, - const std::optional &deviceType) + const std::optional &deviceType, + const std::optional &requestId) { using namespace rest_sink; DevicePtr dev {nullptr}; @@ -861,7 +863,8 @@ namespace mtconnect { const std::optional &from, const std::optional &to, const std::optional &path, bool pretty, - const std::optional &deviceType) + const std::optional &deviceType, + const std::optional &requestId) { using namespace rest_sink; DevicePtr dev {nullptr}; @@ -1022,7 +1025,8 @@ namespace mtconnect { string content = fetchSampleData(asyncResponse->m_printer, asyncResponse->getFilter(), asyncResponse->m_count, from, nullopt, end, - asyncObserver->m_endOfBuffer, asyncResponse->m_pretty); + asyncObserver->m_endOfBuffer, asyncResponse->m_pretty, + asyncResponse->m_requestId); if (m_logStreamData) asyncResponse->m_log << content << endl; @@ -1139,7 +1143,7 @@ namespace mtconnect { asyncResponse->m_session->writeChunk( fetchCurrentData(asyncResponse->m_printer, asyncResponse->m_filter, nullopt, - asyncResponse->m_pretty), + asyncResponse->m_pretty, asyncResponse->m_requestId), boost::asio::bind_executor( m_strand, [this, asyncResponse]() { @@ -1171,7 +1175,8 @@ namespace mtconnect { ResponsePtr RestService::assetRequest(const Printer *printer, const int32_t count, const bool removed, const std::optional &type, - const std::optional &device, bool pretty) + const std::optional &device, bool pretty, + const std::optional &requestId) { using namespace rest_sink; @@ -1189,12 +1194,13 @@ namespace mtconnect { status::ok, printer->printAssets( m_instanceId, uint32_t(m_sinkContract->getAssetStorage()->getMaxAssets()), - uint32_t(m_sinkContract->getAssetStorage()->getCount()), list, pretty), + uint32_t(m_sinkContract->getAssetStorage()->getCount()), list, pretty, requestId), printer->mimeType()); } ResponsePtr RestService::assetIdsRequest(const Printer *printer, - const std::list &ids, bool pretty) + const std::list &ids, bool pretty, + const std::optional &requestId) { using namespace rest_sink; @@ -1208,7 +1214,7 @@ namespace mtconnect { auto message = str.str().substr(0, str.str().size() - 2); return make_unique(status::not_found, - printError(printer, "ASSET_NOT_FOUND", message, pretty), + printError(printer, "ASSET_NOT_FOUND", message, pretty, requestId), printer->mimeType()); } else @@ -1217,7 +1223,7 @@ namespace mtconnect { status::ok, printer->printAssets( m_instanceId, uint32_t(m_sinkContract->getAssetStorage()->getMaxAssets()), - uint32_t(m_sinkContract->getAssetStorage()->getCount()), list, pretty), + uint32_t(m_sinkContract->getAssetStorage()->getCount()), list, pretty, requestId), printer->mimeType()); } } @@ -1403,13 +1409,15 @@ namespace mtconnect { } string RestService::printError(const Printer *printer, const string &errorCode, - const string &text, bool pretty) const + const string &text, bool pretty, + const std::optional &requestId) const { LOG(debug) << "Returning error " << errorCode << ": " << text; if (printer) return printer->printError( m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - m_sinkContract->getCircularBuffer().getSequence(), errorCode, text, pretty); + m_sinkContract->getCircularBuffer().getSequence(), errorCode, text, pretty, + requestId); else return errorCode + ": " + text; } @@ -1485,7 +1493,8 @@ namespace mtconnect { // ------------------------------------------- string RestService::fetchCurrentData(const Printer *printer, const FilterSetOpt &filterSet, - const optional &at, bool pretty) + const optional &at, bool pretty, + const std::optional &requestId) { ObservationList observations; SequenceNumber_t firstSeq, seq; @@ -1509,13 +1518,15 @@ namespace mtconnect { } return printer->printSample(m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - seq, firstSeq, seq - 1, observations, pretty); + seq, firstSeq, seq - 1, observations, pretty, + requestId); } string RestService::fetchSampleData(const Printer *printer, const FilterSetOpt &filterSet, int count, const std::optional &from, const std::optional &to, - SequenceNumber_t &end, bool &endOfBuffer, bool pretty) + SequenceNumber_t &end, bool &endOfBuffer, bool pretty, + const std::optional &requestId) { std::unique_ptr observations; SequenceNumber_t firstSeq, lastSeq; @@ -1545,7 +1556,8 @@ namespace mtconnect { } return printer->printSample(m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - end, firstSeq, lastSeq, *observations, pretty); + end, firstSeq, lastSeq, *observations, pretty, + requestId); } } // namespace sink::rest_sink diff --git a/src/mtconnect/sink/rest_sink/rest_service.hpp b/src/mtconnect/sink/rest_sink/rest_service.hpp index 934231443..5957b401b 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.hpp +++ b/src/mtconnect/sink/rest_sink/rest_service.hpp @@ -101,7 +101,8 @@ namespace mtconnect { ResponsePtr probeRequest(const printer::Printer *p, const std::optional &device = std::nullopt, bool pretty = false, - const std::optional &deviceType = std::nullopt); + const std::optional &deviceType = std::nullopt, + const std::optional &requestId = std::nullopt); /// @brief Handler for a current request /// @param[in] p printer for doc generation @@ -115,7 +116,8 @@ namespace mtconnect { const std::optional &at = std::nullopt, const std::optional &path = std::nullopt, bool pretty = false, - const std::optional &deviceType = std::nullopt); + const std::optional &deviceType = std::nullopt, + const std::optional &requestId = std::nullopt); /// @brief Handler for a sample request /// @param[in] p printer for doc generation @@ -132,7 +134,8 @@ namespace mtconnect { const std::optional &to = std::nullopt, const std::optional &path = std::nullopt, bool pretty = false, - const std::optional &deviceType = std::nullopt); + const std::optional &deviceType = std::nullopt, + const std::optional &requestId = std::nullopt); /// @brief Handler for a streaming sample /// @param[in] session session to stream data to /// @param[in] p printer for doc generation @@ -150,7 +153,7 @@ namespace mtconnect { const std::optional &path = std::nullopt, bool pretty = false, const std::optional &deviceType = std::nullopt, - const std::optional &responseId = std::nullopt); + const std::optional &requestId = std::nullopt); /// @brief Handler for a streaming current /// @param[in] session session to stream data to @@ -164,7 +167,7 @@ namespace mtconnect { const std::optional &path = std::nullopt, bool pretty = false, const std::optional &deviceType = std::nullopt, - const std::optional &responseId = std::nullopt); + const std::optional &requestId = std::nullopt); /// @brief Handler for put/post observation /// @param[in] p printer for response generation /// @param[in] device device @@ -207,7 +210,8 @@ namespace mtconnect { ResponsePtr assetRequest(const printer::Printer *p, const int32_t count, const bool removed, const std::optional &type = std::nullopt, const std::optional &device = std::nullopt, - bool pretty = false); + bool pretty = false, + const std::optional &requestId = std::nullopt); /// @brief Asset request handler using a list of asset ids /// @param[in] p printer for the response document @@ -215,7 +219,8 @@ namespace mtconnect { /// @param[in] pretty `true` to ensure response is formatted /// @return MTConnect Assets response document ResponsePtr assetIdsRequest(const printer::Printer *p, const std::list &ids, - bool pretty = false); + bool pretty = false, + const std::optional &requestId = std::nullopt); /// @brief Asset request handler to update an asset /// @param p printer for the response document @@ -262,7 +267,8 @@ namespace mtconnect { /// @param text descriptive error text /// @return MTConnect Error document std::string printError(const printer::Printer *printer, const std::string &errorCode, - const std::string &text, bool pretty = false) const; + const std::string &text, bool pretty = false, + const std::optional &requestId = std::nullopt) const; /// @name For testing only ///@{ @@ -301,13 +307,15 @@ namespace mtconnect { // Current Data Collection std::string fetchCurrentData(const printer::Printer *printer, const FilterSetOpt &filterSet, - const std::optional &at, bool pretty = false); + const std::optional &at, bool pretty = false, + const std::optional &requestId = std::nullopt); // Sample data collection std::string fetchSampleData(const printer::Printer *printer, const FilterSetOpt &filterSet, int count, const std::optional &from, const std::optional &to, SequenceNumber_t &end, - bool &endOfBuffer, bool pretty = false); + bool &endOfBuffer, bool pretty = false, + const std::optional &requestId = std::nullopt); // Verification methods template From 17f7f375214eef6e8fd0a68eaa58374dc2df4992 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 19 Apr 2024 12:37:28 -0400 Subject: [PATCH 085/128] Added format to all the requests --- src/mtconnect/printer/json_printer.cpp | 23 ++- src/mtconnect/printer/json_printer.hpp | 42 ++--- src/mtconnect/printer/printer.hpp | 46 +++-- src/mtconnect/printer/xml_printer.cpp | 18 +- src/mtconnect/printer/xml_printer.hpp | 40 +++-- src/mtconnect/sink/rest_sink/rest_service.cpp | 166 ++++++++++-------- src/mtconnect/sink/rest_sink/rest_service.hpp | 21 ++- .../sink/rest_sink/websocket_session.hpp | 3 +- 8 files changed, 202 insertions(+), 157 deletions(-) diff --git a/src/mtconnect/printer/json_printer.cpp b/src/mtconnect/printer/json_printer.cpp index c604a6536..3aa2ea39b 100644 --- a/src/mtconnect/printer/json_printer.cpp +++ b/src/mtconnect/printer/json_printer.cpp @@ -60,7 +60,8 @@ namespace mtconnect::printer { template inline void header(AutoJsonObject &obj, const string &version, const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, - const string &schemaVersion, const string modelChangeTime, bool validation) + const string &schemaVersion, const string modelChangeTime, bool validation, + const std::optional &requestId) { obj.AddPairs("version", version, "creationTime", getCurrentTime(GMT), "testIndicator", false, "instanceId", instanceId, "sender", hostname, "schemaVersion", schemaVersion); @@ -71,6 +72,8 @@ namespace mtconnect::printer { obj.AddPairs("bufferSize", bufferSize); if (validation) obj.AddPairs("validation", true); + if (requestId) + obj.AddPairs("requestId", *requestId); } template @@ -78,10 +81,11 @@ namespace mtconnect::printer { const string &hostname, const uint64_t instanceId, const unsigned int bufferSize, const unsigned int assetBufferSize, const unsigned int assetCount, const string &schemaVersion, - const string modelChangeTime, const bool validation) + const string modelChangeTime, const bool validation, + const std::optional &requestId) { header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, - validation); + validation, requestId); obj.AddPairs("assetBufferSize", assetBufferSize, "assetCount", assetCount); } @@ -90,10 +94,11 @@ namespace mtconnect::printer { const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSequence, const uint64_t firstSequence, const uint64_t lastSequence, const string &schemaVersion, - const string modelChangeTime, const bool validation) + const string modelChangeTime, const bool validation, + const std::optional &requestId) { header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, - validation); + validation, requestId); obj.AddPairs("nextSequence", nextSequence, "lastSequence", lastSequence, "firstSequence", firstSequence); } @@ -128,7 +133,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); header(obj, m_version, m_senderName, instanceId, bufferSize, *m_schemaVersion, - m_modelChangeTime, m_validation); + m_modelChangeTime, m_validation, requestId); } { if (m_jsonVersion > 1) @@ -186,7 +191,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); probeAssetHeader(obj, m_version, m_senderName, instanceId, bufferSize, assetBufferSize, - assetCount, *m_schemaVersion, m_modelChangeTime, m_validation); + assetCount, *m_schemaVersion, m_modelChangeTime, m_validation, requestId); } { obj.Key("Devices"); @@ -214,7 +219,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); probeAssetHeader(obj, m_version, m_senderName, instanceId, 0, bufferSize, assetCount, - *m_schemaVersion, m_modelChangeTime, m_validation); + *m_schemaVersion, m_modelChangeTime, m_validation, requestId); } { obj.Key("Assets"); @@ -413,7 +418,7 @@ namespace mtconnect::printer { { AutoJsonObject obj(writer, "Header"); streamHeader(obj, m_version, m_senderName, instanceId, bufferSize, nextSeq, firstSeq, - lastSeq, *m_schemaVersion, m_modelChangeTime, m_validation); + lastSeq, *m_schemaVersion, m_modelChangeTime, m_validation, requestId); } { diff --git a/src/mtconnect/printer/json_printer.hpp b/src/mtconnect/printer/json_printer.hpp index 102cf51ec..119f77b89 100644 --- a/src/mtconnect/printer/json_printer.hpp +++ b/src/mtconnect/printer/json_printer.hpp @@ -30,27 +30,27 @@ namespace mtconnect::printer { JsonPrinter(uint32_t jsonVersion, bool pretty = false, bool validation = false); ~JsonPrinter() override = default; - std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false, - const std::optional requestId = std::nullopt) const override; - - std::string printProbe(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const unsigned int assetBufferSize, - const unsigned int assetCount, const std::list &devices, - const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false, - const std::optional requestId = std::nullopt) const override; - - std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const uint64_t firstSeq, const uint64_t lastSeq, - observation::ObservationList &results, - bool pretty = false, - const std::optional requestId = std::nullopt) const override; - std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, - const unsigned int assetCount, const asset::AssetList &asset, - bool pretty = false, - const std::optional requestId = std::nullopt) const override; + std::string printErrors( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const ProtoErrorList &list, bool pretty = false, + const std::optional requestId = std::nullopt) const override; + + std::string printProbe( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const unsigned int assetBufferSize, const unsigned int assetCount, + const std::list &devices, const std::map *count = nullptr, + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const override; + + std::string printSample( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, + bool pretty = false, + const std::optional requestId = std::nullopt) const override; + std::string printAssets( + const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, + const asset::AssetList &asset, bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string mimeType() const override { return "application/mtconnect+json"; } uint32_t getJsonVersion() const { return m_jsonVersion; } diff --git a/src/mtconnect/printer/printer.hpp b/src/mtconnect/printer/printer.hpp index 38727109f..d6526a98b 100644 --- a/src/mtconnect/printer/printer.hpp +++ b/src/mtconnect/printer/printer.hpp @@ -61,10 +61,10 @@ namespace mtconnect { /// @param[in] errorCode an error code /// @param[in] errorText the error text /// @return the error document - virtual std::string printError(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const std::string &errorCode, - const std::string &errorText, bool pretty = false, - const std::optional requestId = std::nullopt) const + virtual std::string printError( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const std::string &errorCode, const std::string &errorText, bool pretty = false, + const std::optional requestId = std::nullopt) const { return printErrors(instanceId, bufferSize, nextSeq, {{errorCode, errorText}}); } @@ -74,10 +74,10 @@ namespace mtconnect { /// @param[in] nextSeq the next sequence /// @param[in] list the list of errors /// @return the MTConnect Error document - virtual std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false, - const std::optional requestId = std::nullopt) const = 0; + virtual std::string printErrors( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const ProtoErrorList &list, bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief Generate an MTConnect Devices document /// @param[in] instanceId the instance id /// @param[in] bufferSize the buffer size @@ -87,13 +87,12 @@ namespace mtconnect { /// @param[in] devices a list of devices /// @param[in] count optional asset count and type association /// @return the MTConnect Devices document - virtual std::string printProbe(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const unsigned int assetBufferSize, - const unsigned int assetCount, - const std::list &devices, - const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false, - const std::optional requestId = std::nullopt) const = 0; + virtual std::string printProbe( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const unsigned int assetBufferSize, const unsigned int assetCount, + const std::list &devices, const std::map *count = nullptr, + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief Print a MTConnect Streams document /// @param[in] instanceId the instance id /// @param[in] bufferSize the buffer size @@ -102,21 +101,20 @@ namespace mtconnect { /// @param[in] lastSeq the last sequnce /// @param[in] results a list of observations /// @return the MTConnect Streams document - virtual std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const uint64_t firstSeq, - const uint64_t lastSeq, observation::ObservationList &results, - bool pretty = false, - const std::optional requestId = std::nullopt) const = 0; + virtual std::string printSample( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, + bool pretty = false, const std::optional requestId = std::nullopt) const = 0; /// @brief Generate an MTConnect Assets document /// @param[in] anInstanceId the instance id /// @param[in] bufferSize the buffer size /// @param[in] assetCount the asset count /// @param[in] asset the list of assets /// @return the MTConnect Assets document - virtual std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, - const unsigned int assetCount, asset::AssetList const &asset, - bool pretty = false, - const std::optional requestId = std::nullopt) const = 0; + virtual std::string printAssets( + const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, + asset::AssetList const &asset, bool pretty = false, + const std::optional requestId = std::nullopt) const = 0; /// @brief get the mime type for the documents /// @return the mime type virtual std::string mimeType() const = 0; diff --git a/src/mtconnect/printer/xml_printer.cpp b/src/mtconnect/printer/xml_printer.cpp index 75232f818..c5ae680c1 100644 --- a/src/mtconnect/printer/xml_printer.cpp +++ b/src/mtconnect/printer/xml_printer.cpp @@ -352,8 +352,8 @@ namespace mtconnect::printer { { XmlWriter writer(m_pretty || pretty); - initXmlDoc(writer, eERROR, instanceId, bufferSize, 0, 0, nextSeq, 0, nextSeq - 1, - nullptr, requestId); + initXmlDoc(writer, eERROR, instanceId, bufferSize, 0, 0, nextSeq, 0, nextSeq - 1, nullptr, + requestId); { AutoElement e1(writer, "Errors"); @@ -443,8 +443,8 @@ namespace mtconnect::printer { string XmlPrinter::printSample(const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, const uint64_t firstSeq, - const uint64_t lastSeq, ObservationList &observations, - bool pretty, const std::optional requestId) const + const uint64_t lastSeq, ObservationList &observations, bool pretty, + const std::optional requestId) const { string ret; @@ -524,16 +524,15 @@ namespace mtconnect::printer { } string XmlPrinter::printAssets(const uint64_t instanceId, const unsigned int bufferSize, - const unsigned int assetCount, const AssetList &asset, - bool pretty, + const unsigned int assetCount, const AssetList &asset, bool pretty, const std::optional requestId) const { string ret; try { XmlWriter writer(m_pretty || pretty); - initXmlDoc(writer, eASSETS, instanceId, 0u, bufferSize, assetCount, 0ull, - 0, 0, nullptr, requestId); + initXmlDoc(writer, eASSETS, instanceId, 0u, bufferSize, assetCount, 0ull, 0, 0, nullptr, + requestId); { AutoElement ele(writer, "Assets"); @@ -676,11 +675,10 @@ namespace mtconnect::printer { sprintf(version, "%d.%d.%d.%d", AGENT_VERSION_MAJOR, AGENT_VERSION_MINOR, AGENT_VERSION_PATCH, AGENT_VERSION_BUILD); addAttribute(writer, "version", version); - + if (requestId) addAttribute(writer, "requestId", *requestId); - int major, minor; char c; stringstream v(*m_schemaVersion); diff --git a/src/mtconnect/printer/xml_printer.hpp b/src/mtconnect/printer/xml_printer.hpp index 71a2ef90e..0ab050bef 100644 --- a/src/mtconnect/printer/xml_printer.hpp +++ b/src/mtconnect/printer/xml_printer.hpp @@ -43,25 +43,27 @@ namespace mtconnect { XmlPrinter(bool pretty = false, bool validation = false); ~XmlPrinter() override = default; - std::string printErrors(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const ProtoErrorList &list, - bool pretty = false, - const std::optional requestId = std::nullopt) const override; - - std::string printProbe(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const unsigned int assetBufferSize, - const unsigned int assetCount, const std::list &devices, - const std::map *count = nullptr, - bool includeHidden = false, bool pretty = false, - const std::optional requestId = std::nullopt) const override; - - std::string printSample(const uint64_t instanceId, const unsigned int bufferSize, - const uint64_t nextSeq, const uint64_t firstSeq, - const uint64_t lastSeq, observation::ObservationList &results, - bool pretty = false, const std::optional requestId = std::nullopt) const override; - std::string printAssets(const uint64_t anInstanceId, const unsigned int bufferSize, - const unsigned int assetCount, const asset::AssetList &asset, - bool pretty = false, const std::optional requestId = std::nullopt) const override; + std::string printErrors( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const ProtoErrorList &list, bool pretty = false, + const std::optional requestId = std::nullopt) const override; + + std::string printProbe( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const unsigned int assetBufferSize, const unsigned int assetCount, + const std::list &devices, const std::map *count = nullptr, + bool includeHidden = false, bool pretty = false, + const std::optional requestId = std::nullopt) const override; + + std::string printSample( + const uint64_t instanceId, const unsigned int bufferSize, const uint64_t nextSeq, + const uint64_t firstSeq, const uint64_t lastSeq, observation::ObservationList &results, + bool pretty = false, + const std::optional requestId = std::nullopt) const override; + std::string printAssets( + const uint64_t anInstanceId, const unsigned int bufferSize, const unsigned int assetCount, + const asset::AssetList &asset, bool pretty = false, + const std::optional requestId = std::nullopt) const override; std::string mimeType() const override { return "text/xml"; } /// @brief Print a single device in XML diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 0f585e8b2..eb86d0f06 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -113,6 +113,7 @@ namespace mtconnect { {"from", QUERY, "Sequence number at to start reporting observations"}, {"interval", QUERY, "Time in ms between publishing data–starts streaming"}, {"pretty", QUERY, "Instructs the result to be pretty printed"}, + {"format", QUERY, "The format of the response document: 'xml' or 'json'"}, {"heartbeat", QUERY, "Time in ms between publishing a empty document when no data has changed"}}); @@ -475,8 +476,8 @@ namespace mtconnect { auto device = request->parameter("device"); auto pretty = *request->parameter("pretty"); auto deviceType = request->parameter("deviceType"); - - auto printer = printerForAccepts(request->m_accepts); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); if (device && !ends_with(request->m_path, string("probe")) && m_sinkContract->findDeviceByUUIDorName(*device) == nullptr) @@ -487,19 +488,21 @@ namespace mtconnect { return false; } - respond(session, probeRequest(printer, device, pretty, deviceType), request->m_requestId); + respond(session, probeRequest(printer, device, pretty, deviceType, request->m_requestId), + request->m_requestId); return true; }; m_server ->addRouting({boost::beast::http::verb::get, - "/probe?pretty={bool:false}&deviceType={string}", handler}) + "/probe?pretty={bool:false}&deviceType={string}&format={string}", handler}) .document("MTConnect probe request", "Provides metadata service for the MTConnect Devices information model for all " "devices."); m_server ->addRouting({boost::beast::http::verb::get, - "/{device}/probe?pretty={bool:false}&deviceType={string}", handler}) + "/{device}/probe?pretty={bool:false}&deviceType={string}&format={string}", + handler}) .document("MTConnect probe request", "Provides metadata service for the MTConnect Devices information model for " "device identified by `device` matching `name` or `uuid`.") @@ -507,14 +510,15 @@ namespace mtconnect { // Must be last m_server - ->addRouting( - {boost::beast::http::verb::get, "/?pretty={bool:false}&deviceType={string}", handler}) + ->addRouting({boost::beast::http::verb::get, + "/?pretty={bool:false}&deviceType={string}&format={string}", handler}) .document("MTConnect probe request", "Provides metadata service for the MTConnect Devices information model for all " "devices."); m_server ->addRouting({boost::beast::http::verb::get, - "/{device}?pretty={bool:false}&deviceType={string}", handler}) + "/{device}?pretty={bool:false}&deviceType={string}&format={string}", + handler}) .document("MTConnect probe request", "Provides metadata service for the MTConnect Devices information model for " "device identified by `device` matching `name` or `uuid`."); @@ -526,12 +530,13 @@ namespace mtconnect { auto handler = [&](SessionPtr session, RequestPtr request) -> bool { auto removed = *request->parameter("removed"); auto count = *request->parameter("count"); - auto printer = printerForAccepts(request->m_accepts); - auto pretty = request->parameter("pretty").value_or(false); + auto pretty = *request->parameter("pretty"); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); respond(session, assetRequest(printer, count, removed, request->parameter("type"), - request->parameter("device"), pretty), + request->parameter("device"), pretty, request->m_requestId), request->m_requestId); return true; }; @@ -541,20 +546,24 @@ namespace mtconnect { auto pretty = request->parameter("pretty").value_or(false); if (asset) { - auto printer = m_sinkContract->getPrinter(acceptFormat(request->m_accepts)); + auto format = request->parameter("format"); + auto pretty = *request->parameter("pretty"); + auto printer = m_sinkContract->getPrinter(acceptFormat(request->m_accepts, format)); list ids; stringstream str(*asset); string id; while (getline(str, id, ';')) ids.emplace_back(id); - respond(session, assetIdsRequest(printer, ids, pretty), request->m_requestId); + respond(session, assetIdsRequest(printer, ids, pretty, request->m_requestId), + request->m_requestId); } else { - auto printer = printerForAccepts(request->m_accepts); - auto pretty = *request->parameter("pretty"); - auto error = printError(printer, "INVALID_REQUEST", "No asset given", pretty); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + auto error = printError(printer, "INVALID_REQUEST", "No asset given"); + respond(session, make_unique(rest_sink::status::bad_request, error, printer->mimeType()), request->m_requestId); @@ -564,7 +573,7 @@ namespace mtconnect { string qp( "type={string}&removed={bool:false}&" - "count={integer:100}&device={string}&pretty={bool:false}"); + "count={integer:100}&device={string}&pretty={bool:false}&format={string}"); m_server->addRouting({boost::beast::http::verb::get, "/assets?" + qp, handler}) .document("MTConnect assets request", "Returns up to `count` assets"); m_server->addRouting({boost::beast::http::verb::get, "/asset?" + qp, handler}) @@ -585,7 +594,8 @@ namespace mtconnect { if (m_server->arePutsAllowed()) { auto putHandler = [&](SessionPtr session, RequestPtr request) -> bool { - auto printer = printerForAccepts(request->m_accepts); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); respond(session, putAssetRequest(printer, request->m_body, request->parameter("type"), request->parameter("device"), @@ -601,7 +611,8 @@ namespace mtconnect { list ids; stringstream str(*asset); string id; - auto printer = printerForAccepts(request->m_accepts); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); while (getline(str, id, ';')) ids.emplace_back(id); @@ -609,9 +620,11 @@ namespace mtconnect { } else { + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + respond(session, - deleteAllAssetsRequest(printerForAccepts(request->m_accepts), - request->parameter("device"), + deleteAllAssetsRequest(printer, request->parameter("device"), request->parameter("type")), request->m_requestId); } @@ -625,34 +638,42 @@ namespace mtconnect { { m_server ->addRouting( - {t, "/" + asset + "/{assetId}?device={string}&type={string}", putHandler}) + {t, "/" + asset + "/{assetId}?device={string}&type={string}&format={string}", + putHandler}) .document("Upload an asset by identified by `assetId`", "Updates or adds an asset with the asset XML in the body"); - m_server->addRouting({t, "/" + asset + "?device={string}&type={string}", putHandler}) + m_server + ->addRouting( + {t, "/" + asset + "?device={string}&type={string}&format={string}", putHandler}) .document("Upload an asset by identified by `assetId`", "Updates or adds an asset with the asset XML in the body"); - m_server->addRouting({t, "/{device}/" + asset + "/{assetId}?type={string}", putHandler}) + m_server + ->addRouting({t, "/{device}/" + asset + "/{assetId}?type={string}&format={string}", + putHandler}) .document("Upload an asset by identified by `assetId`", "Updates or adds an asset with the asset XML in the body"); - m_server->addRouting({t, "/{device}/" + asset + "?type={string}", putHandler}) + m_server + ->addRouting( + {t, "/{device}/" + asset + "?type={string}&format={string}", putHandler}) .document("Upload an asset by identified by `assetId`", "Updates or adds an asset with the asset XML in the body"); } m_server ->addRouting({boost::beast::http::verb::delete_, - "/" + asset + "?device={string}&type={string}", deleteHandler}) + "/" + asset + "?device={string}&type={string}&format={string}", + deleteHandler}) .document("Delete all assets for a device and type", "Device and type are optional. If they are not given, it assumes there is " "no constraint"); m_server - ->addRouting( - {boost::beast::http::verb::delete_, "/" + asset + "/{assetId}", deleteHandler}) + ->addRouting({boost::beast::http::verb::delete_, + "/" + asset + "/{assetId}?format={string}", deleteHandler}) .document("Delete asset identified by `assetId`", "Marks the asset as removed and creates an AssetRemoved event"); m_server ->addRouting({boost::beast::http::verb::delete_, - "/{device}/" + asset + "?type={string}", deleteHandler}) + "/{device}/" + asset + "?type={string}&format={string}", deleteHandler}) .document("Delete all assets for a device and type", "Device and type are optional. If they are not given, it assumes there is " "no constraint") @@ -669,20 +690,25 @@ namespace mtconnect { auto interval = request->parameter("interval"); if (interval) { - streamCurrentRequest(session, printerForAccepts(request->m_accepts), *interval, - request->parameter("device"), + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + + streamCurrentRequest(session, printer, *interval, request->parameter("device"), request->parameter("path"), *request->parameter("pretty"), request->parameter("deviceType"), request->m_requestId); } else { + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + respond( session, - currentRequest( - printerForAccepts(request->m_accepts), request->parameter("device"), - request->parameter("at"), request->parameter("path"), - *request->parameter("pretty"), request->parameter("deviceType")), + currentRequest(printer, request->parameter("device"), + request->parameter("at"), request->parameter("path"), + *request->parameter("pretty"), + request->parameter("deviceType"), request->m_requestId), request->m_requestId); } return true; @@ -691,7 +717,7 @@ namespace mtconnect { string qp( "path={string}&at={unsigned_integer}&" "interval={integer}&pretty={bool:false}&" - "deviceType={string}"); + "deviceType={string}&format={string}"); m_server->addRouting({boost::beast::http::verb::get, "/current?" + qp, handler}) .document("MTConnect current request", "Gets a stapshot of the state of all the observations for all devices " @@ -710,23 +736,29 @@ namespace mtconnect { auto interval = request->parameter("interval"); if (interval) { + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + streamSampleRequest( - session, printerForAccepts(request->m_accepts), *interval, - *request->parameter("heartbeat"), *request->parameter("count"), - request->parameter("device"), request->parameter("from"), - request->parameter("path"), *request->parameter("pretty"), - request->parameter("deviceType"), request->m_requestId); + session, printer, *interval, *request->parameter("heartbeat"), + *request->parameter("count"), request->parameter("device"), + request->parameter("from"), request->parameter("path"), + *request->parameter("pretty"), request->parameter("deviceType"), + request->m_requestId); } else { - respond( - session, - sampleRequest( - printerForAccepts(request->m_accepts), *request->parameter("count"), - request->parameter("device"), request->parameter("from"), - request->parameter("to"), request->parameter("path"), - *request->parameter("pretty"), request->parameter("deviceType")), - request->m_requestId); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); + + respond(session, + sampleRequest( + printer, *request->parameter("count"), + request->parameter("device"), request->parameter("from"), + request->parameter("to"), request->parameter("path"), + *request->parameter("pretty"), request->parameter("deviceType"), + request->m_requestId), + request->m_requestId); } return true; }; @@ -736,7 +768,7 @@ namespace mtconnect { "interval={integer}&count={integer:100}&" "heartbeat={integer:10000}&to={unsigned_integer}&" "pretty={bool:false}&" - "deviceType={string}"); + "deviceType={string}&format={string}"); m_server->addRouting({boost::beast::http::verb::get, "/sample?" + qp, handler}) .document("MTConnect sample request", "Gets a time series of at maximum `count` observations for all devices " @@ -764,11 +796,11 @@ namespace mtconnect { if (ts) queries.erase("time"); auto device = request->parameter("device"); + auto format = request->parameter("format"); + auto printer = getPrinter(request->m_accepts, format); - respond( - session, - putObservationRequest(printerForAccepts(request->m_accepts), *device, queries, ts), - request->m_requestId); + respond(session, putObservationRequest(printer, *device, queries, ts), + request->m_requestId); return true; } else @@ -828,7 +860,7 @@ namespace mtconnect { m_sinkContract->getCircularBuffer().getSequence(), uint32_t(m_sinkContract->getAssetStorage()->getMaxAssets()), uint32_t(m_sinkContract->getAssetStorage()->getCount()), deviceList, - &counts, false, pretty), + &counts, false, pretty, requestId), printer->mimeType()); } @@ -854,7 +886,7 @@ namespace mtconnect { // Check if there is a frequency to stream data or not return make_unique(rest_sink::status::ok, - fetchCurrentData(printer, filter, at, pretty), + fetchCurrentData(printer, filter, at, pretty, requestId), printer->mimeType()); } @@ -885,7 +917,7 @@ namespace mtconnect { return make_unique( rest_sink::status::ok, - fetchSampleData(printer, filter, count, from, to, end, endOfBuffer, pretty), + fetchSampleData(printer, filter, count, from, to, end, endOfBuffer, pretty, requestId), printer->mimeType()); } @@ -1213,9 +1245,9 @@ namespace mtconnect { str << id << ", "; auto message = str.str().substr(0, str.str().size() - 2); - return make_unique(status::not_found, - printError(printer, "ASSET_NOT_FOUND", message, pretty, requestId), - printer->mimeType()); + return make_unique( + status::not_found, printError(printer, "ASSET_NOT_FOUND", message, pretty, requestId), + printer->mimeType()); } else { @@ -1403,11 +1435,6 @@ namespace mtconnect { return "xml"; } - const Printer *RestService::printerForAccepts(const std::string &accepts) const - { - return m_sinkContract->getPrinter(acceptFormat(accepts)); - } - string RestService::printError(const Printer *printer, const string &errorCode, const string &text, bool pretty, const std::optional &requestId) const @@ -1416,8 +1443,7 @@ namespace mtconnect { if (printer) return printer->printError( m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - m_sinkContract->getCircularBuffer().getSequence(), errorCode, text, pretty, - requestId); + m_sinkContract->getCircularBuffer().getSequence(), errorCode, text, pretty, requestId); else return errorCode + ": " + text; } @@ -1518,8 +1544,7 @@ namespace mtconnect { } return printer->printSample(m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - seq, firstSeq, seq - 1, observations, pretty, - requestId); + seq, firstSeq, seq - 1, observations, pretty, requestId); } string RestService::fetchSampleData(const Printer *printer, const FilterSetOpt &filterSet, @@ -1556,8 +1581,7 @@ namespace mtconnect { } return printer->printSample(m_instanceId, m_sinkContract->getCircularBuffer().getBufferSize(), - end, firstSeq, lastSeq, *observations, pretty, - requestId); + end, firstSeq, lastSeq, *observations, pretty, requestId); } } // namespace sink::rest_sink diff --git a/src/mtconnect/sink/rest_sink/rest_service.hpp b/src/mtconnect/sink/rest_sink/rest_service.hpp index 5957b401b..f58c7df28 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.hpp +++ b/src/mtconnect/sink/rest_sink/rest_service.hpp @@ -259,7 +259,26 @@ namespace mtconnect { /// @brief get a printer given a list of formats from the Accepts header /// @param accepts the accepts header /// @return pointer to a printer - const printer::Printer *printerForAccepts(const std::string &accepts) const; + const printer::Printer *printerForAccepts(const std::string &accepts) const + { + return m_sinkContract->getPrinter(acceptFormat(accepts)); + } + + /// @brief get a printer for a format or using the accepts header. Falls back to header accept + /// if format incorrect. + /// @param accepts the accept header of the request + /// @param format optional format query param + /// @return pointer to a printer + const printer::Printer *getPrinter(const std::string &accepts, + std::optional format) const + { + const printer::Printer *printer = nullptr; + if (format) + printer = m_sinkContract->getPrinter(*format); + if (printer == nullptr) + printer = printerForAccepts(accepts); + return printer; + } /// @brief Generate an MTConnect Error document /// @param printer printer to generate error diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index fcf91939e..e8677ebdb 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -421,14 +421,13 @@ namespace mtconnect::sink::rest_sink { m_request.reset(); closeStream(); } - + void closeStream() override { if (m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } - auto getExecutor() { return m_stream.get_executor(); } auto &stream() { return m_stream; } From 71f28cafa2dc0be3a00f50a876103cf9c8f7c160 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 17:03:48 -0400 Subject: [PATCH 086/128] Fixed session leak with observer circular ref in handler. --- src/mtconnect/observation/change_observer.hpp | 15 ++++ .../sink/mqtt_sink/mqtt2_service.cpp | 5 ++ src/mtconnect/sink/rest_sink/rest_service.cpp | 9 +++ src/mtconnect/sink/rest_sink/session.hpp | 8 ++ .../sink/rest_sink/websocket_session.hpp | 75 +++++++++++++------ 5 files changed, 91 insertions(+), 21 deletions(-) diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index 3f4e5c2eb..439439156 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -142,6 +142,14 @@ namespace mtconnect::observation { /// @brief try to lock the mutex auto try_lock() { return m_mutex.try_lock(); } ///@} + + /// @brief clear the observer information. + void clear() + { + std::unique_lock lock(m_mutex); + m_signalers.clear(); + m_handler.clear(); + } private: boost::asio::io_context::strand &m_strand; @@ -237,6 +245,13 @@ namespace mtconnect::observation { /// @brief method to determine if the sink is running virtual bool isRunning() = 0; + + /// @brief Stop all timers and release resources. + virtual bool cancel() + { + m_observer.clear(); + return true; + } /// @brief handler callback when an action needs to be taken /// diff --git a/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp index ed3123a9b..76ae46844 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp @@ -205,6 +205,11 @@ namespace mtconnect { auto client = m_client.lock(); return client && client->isRunning() && client->isConnected(); } + + bool cancel() override + { + return true; + } DevicePtr m_device; std::weak_ptr m_client; diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index eb86d0f06..c8c3fbcfb 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -937,6 +937,7 @@ namespace mtconnect { if (sink && isRunning()) { m_session->fail(status, message); + cancel(); } else { @@ -962,6 +963,13 @@ namespace mtconnect { return server->isRunning(); } } + + bool cancel() override + { + observation::AsyncObserver::cancel(); + m_session.reset(); + return true; + } std::weak_ptr m_sink; //! weak shared pointer to the sink. handles shutdown timer race @@ -1015,6 +1023,7 @@ namespace mtconnect { asyncResponse->m_sink = getptr(); asyncResponse->m_pretty = pretty; asyncResponse->m_requestId = requestId; + session->addObserver(asyncResponse); if (m_logStreamData) { diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index 4e2bc52ab..8d3f76412 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -25,6 +25,7 @@ #include #include "mtconnect/config.hpp" +#include "mtconnect/observation/change_observer.hpp" #include "routing.hpp" namespace mtconnect::sink::rest_sink { @@ -117,6 +118,12 @@ namespace mtconnect::sink::rest_sink { m_message = msg; m_unauthorized = true; } + + /// @brief Add an observer to the list for cleanup later. + void addObserver(std::weak_ptr observer) + { + m_observers.push_back(observer); + } protected: Dispatch m_dispatch; @@ -127,6 +134,7 @@ namespace mtconnect::sink::rest_sink { bool m_allowPuts {false}; std::set m_allowPutsFrom; boost::asio::ip::tcp::endpoint m_remote; + std::list> m_observers; }; } // namespace mtconnect::sink::rest_sink diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index e8677ebdb..e38b0c4dd 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -96,6 +96,29 @@ namespace mtconnect::sink::rest_sink { beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr()))); } + + void close() override + { + NAMED_SCOPE("PlainWebsocketSession::close"); + if (!m_isOpen) + return; + + auto ptr = derived().shared_ptr(); + + m_request.reset(); + m_requests.clear(); + for (auto obs : m_observers) + { + auto optr = obs.lock(); + if (optr) + { + optr->cancel(); + } + } + closeStream(); + + m_isOpen = false; + } void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { @@ -128,7 +151,9 @@ namespace mtconnect::sink::rest_sink { req.m_streaming = true; if (complete) + { complete(); + } } else { @@ -145,6 +170,12 @@ namespace mtconnect::sink::rest_sink { std::optional requestId = std::nullopt) override { NAMED_SCOPE("WebsocketSession::writeChunk"); + + if (!derived().stream().is_open()) + { + return; + } + if (requestId) { LOG(trace) << "Waiting for mutex"; @@ -173,6 +204,8 @@ namespace mtconnect::sink::rest_sink { fail(status::internal_server_error, "Error occurred in accpet", ec); return; } + + m_isOpen = true; derived().stream().async_read( m_buffer, beast::bind_front_handler(&WebsocketSession::onRead, derived().shared_ptr())); @@ -188,7 +221,7 @@ namespace mtconnect::sink::rest_sink { if (it != m_requests.end()) { auto &req = it->second; - req.m_complete = complete; + req.m_complete = std::move(complete); req.m_streamBuffer.emplace(); std::ostream str(&req.m_streamBuffer.value()); @@ -236,6 +269,7 @@ namespace mtconnect::sink::rest_sink { if (req.m_complete) { boost::asio::post(derived().stream().get_executor(), req.m_complete); + req.m_complete = nullptr; } if (!req.m_streaming) @@ -277,6 +311,12 @@ namespace mtconnect::sink::rest_sink { using namespace rapidjson; using namespace std; + + if (len == 0) + { + LOG(trace) << "Empty message received"; + return; + } // Parse the buffer as a JSON request with parameters matching // REST API @@ -395,6 +435,7 @@ namespace mtconnect::sink::rest_sink { std::mutex m_mutex; std::atomic_bool m_busy; std::deque m_messageQueue; + bool m_isOpen { false }; }; template @@ -412,19 +453,15 @@ namespace mtconnect::sink::rest_sink { { beast::get_lowest_layer(m_stream).expires_never(); } - ~PlainWebsocketSession() { close(); } - - void close() override - { - NAMED_SCOPE("PlainWebsocketSession::close"); - - m_request.reset(); - closeStream(); + ~PlainWebsocketSession() + { + if (m_isOpen) + close(); } void closeStream() override { - if (m_stream.is_open()) + if (m_isOpen && m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } @@ -455,23 +492,19 @@ namespace mtconnect::sink::rest_sink { { beast::get_lowest_layer(m_stream).expires_never(); } - ~TlsWebsocketSession() { close(); } - + ~TlsWebsocketSession() + { + if (m_isOpen) + close(); + } + auto &stream() { return m_stream; } auto getExecutor() { return m_stream.get_executor(); } - void close() override - { - NAMED_SCOPE("TlsWebsocketSession::close"); - - m_request.reset(); - closeStream(); - } - void closeStream() override { - if (m_stream.is_open()) + if (m_isOpen && m_stream.is_open()) m_stream.close(beast::websocket::close_code::none); } From 4f3cca493906d176037654bc7f3909ea19c07044 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 17:07:11 -0400 Subject: [PATCH 087/128] Added code to session impl as well. --- src/mtconnect/sink/rest_sink/session_impl.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index 40777da00..f1eeef2e5 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -527,6 +527,18 @@ namespace mtconnect::sink::rest_sink { if (!m_closing) { m_closing = true; + + // Release all references from observers. + for (auto obs : m_observers) + { + auto optr = obs.lock(); + if (optr) + { + optr->cancel(); + } + } + + // Set the timeout. beast::get_lowest_layer(m_stream).expires_after(std::chrono::seconds(30)); From dff313dbee21969df95b51b956ca2196160014ee Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 17:11:05 -0400 Subject: [PATCH 088/128] Fixed test issues --- test_package/agent_test_helper.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test_package/agent_test_helper.hpp b/test_package/agent_test_helper.hpp index 13c14fc94..a0f93a0bb 100644 --- a/test_package/agent_test_helper.hpp +++ b/test_package/agent_test_helper.hpp @@ -78,13 +78,15 @@ namespace mtconnect { writeResponse(std::move(response), complete); } } - void beginStreaming(const std::string &mimeType, Complete complete) override + void beginStreaming(const std::string &mimeType, Complete complete, + std::optional requestId = std::nullopt) override { m_mimeType = mimeType; m_streaming = true; complete(); } - void writeChunk(const std::string &chunk, Complete complete) override + void writeChunk(const std::string &chunk, Complete complete, + std::optional requestId = std::nullopt) override { m_chunkBody = chunk; if (m_streaming) From c0aebe2fc1ca839db7730d8c7f1461ee9ded6485 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 17:33:08 -0400 Subject: [PATCH 089/128] fixed bug in dispatch --- src/mtconnect/sink/rest_sink/routing.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index 230534222..0710f15b1 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -187,6 +187,10 @@ namespace mtconnect::sink::rest_sink { } } } + else + { + return false; + } } for (auto &p : m_queryParameters) From 3abfb5e9edaeb06ed5594b27a7532f9201d5822f Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 21:31:27 -0400 Subject: [PATCH 090/128] refactored mqtt sinks and tests. Added cancel to websockets --- agent_lib/CMakeLists.txt | 8 +- src/mtconnect/configuration/agent_config.cpp | 4 +- src/mtconnect/observation/change_observer.hpp | 16 +- .../sink/mqtt_sink/mqtt2_service.cpp | 404 ----------- .../sink/mqtt_sink/mqtt2_service.hpp | 241 ------- .../sink/mqtt_sink/mqtt_legacy_service.cpp | 197 ++++++ .../sink/mqtt_sink/mqtt_legacy_service.hpp | 107 +++ src/mtconnect/sink/mqtt_sink/mqtt_service.cpp | 297 +++++++-- src/mtconnect/sink/mqtt_sink/mqtt_service.hpp | 108 ++- src/mtconnect/sink/rest_sink/rest_service.cpp | 22 +- src/mtconnect/sink/rest_sink/session.hpp | 16 +- src/mtconnect/sink/rest_sink/session_impl.cpp | 3 +- .../sink/rest_sink/websocket_session.hpp | 26 +- test_package/CMakeLists.txt | 2 +- test_package/agent_test_helper.hpp | 40 +- test_package/mqtt_isolated_test.cpp | 2 +- test_package/mqtt_legacy_sink_test.cpp | 630 ++++++++++++++++++ test_package/mqtt_sink_2_test.cpp | 434 ------------ test_package/mqtt_sink_test.cpp | 407 +++-------- 19 files changed, 1451 insertions(+), 1513 deletions(-) delete mode 100644 src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp delete mode 100644 src/mtconnect/sink/mqtt_sink/mqtt2_service.hpp create mode 100644 src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp create mode 100644 src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp create mode 100644 test_package/mqtt_legacy_sink_test.cpp delete mode 100644 test_package/mqtt_sink_2_test.cpp diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index 6f5a9e4fe..5b4ae0a40 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -244,13 +244,13 @@ set(AGENT_SOURCES # src/sink/mqtt_sink HEADER_FILE_ONLY - "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.hpp" - "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.hpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.hpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.hpp" #src/sink/mqtt_sink SOURCE_FILES_ONLY - "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" - "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.cpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.cpp" + "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" # src/sink/rest_sink HEADER_FILE_ONLY diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index 59dc8a360..e9c22d4be 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -58,7 +58,7 @@ #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/device_model/device.hpp" #include "mtconnect/printer/xml_printer.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt2_service.hpp" +#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" #include "mtconnect/sink/mqtt_sink/mqtt_service.hpp" #include "mtconnect/sink/rest_sink/rest_service.hpp" #include "mtconnect/source/adapter/agent_adapter/agent_adapter.hpp" @@ -112,8 +112,8 @@ namespace mtconnect::configuration { bool success = false; + sink::mqtt_sink::MqttLegacyService::registerFactory(m_sinkFactory); sink::mqtt_sink::MqttService::registerFactory(m_sinkFactory); - sink::mqtt_sink::Mqtt2Service::registerFactory(m_sinkFactory); sink::rest_sink::RestService::registerFactory(m_sinkFactory); adapter::shdr::ShdrAdapter::registerFactory(m_sourceFactory); adapter::mqtt_adapter::MqttAdapter::registerFactory(m_sourceFactory); diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index 439439156..b38cc6161 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -142,13 +142,14 @@ namespace mtconnect::observation { /// @brief try to lock the mutex auto try_lock() { return m_mutex.try_lock(); } ///@} - + /// @brief clear the observer information. void clear() { std::unique_lock lock(m_mutex); - m_signalers.clear(); + m_signalers.clear(); m_handler.clear(); + m_timer.cancel(); } private: @@ -245,7 +246,7 @@ namespace mtconnect::observation { /// @brief method to determine if the sink is running virtual bool isRunning() = 0; - + /// @brief Stop all timers and release resources. virtual bool cancel() { @@ -265,9 +266,15 @@ namespace mtconnect::observation { auto getSequence() const { return m_sequence; } auto isEndOfBuffer() const { return m_endOfBuffer; } const auto &getFilter() const { return m_filter; } + const auto &getRequestId() const { return m_requestId; } + ///@} + ///@{ + /// @name setters + + /// @brief sets the optonal request id for webservices. + void setRequestId(const std::optional &id) { m_requestId = id; } ///@} - /// mutable bool m_endOfBuffer {false}; //! Public indicator that we are at the end of the buffer @@ -291,5 +298,6 @@ namespace mtconnect::observation { ChangeObserver m_observer; //! the change observer mtconnect::buffer::CircularBuffer &m_buffer; //! reference to the circular buffer + std::optional m_requestId; //! request id }; } // namespace mtconnect::observation diff --git a/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp deleted file mode 100644 index 76ae46844..000000000 --- a/src/mtconnect/sink/mqtt_sink/mqtt2_service.cpp +++ /dev/null @@ -1,404 +0,0 @@ -// -// Copyright Copyright 2009-2023, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#include "mqtt2_service.hpp" - -#include - -#include "mtconnect/configuration/config_options.hpp" -#include "mtconnect/entity/entity.hpp" -#include "mtconnect/entity/factory.hpp" -#include "mtconnect/entity/json_parser.hpp" -#include "mtconnect/mqtt/mqtt_client_impl.hpp" -#include "mtconnect/printer/json_printer.hpp" - -using ptree = boost::property_tree::ptree; -using json = nlohmann::json; - -using namespace std; -using namespace mtconnect; -using namespace mtconnect::asset; - -namespace asio = boost::asio; -namespace config = ::mtconnect::configuration; - -namespace mtconnect { - namespace sink { - namespace mqtt_sink { - // get obeservation in - // create a json printer - // call print - - Mqtt2Service::Mqtt2Service(boost::asio::io_context &context, sink::SinkContractPtr &&contract, - const ConfigOptions &options, const ptree &config) - : Sink("Mqtt2Service", std::move(contract)), - m_context(context), - m_strand(context), - m_options(options), - m_currentTimer(context) - { - // Unique id number for agent instance - m_instanceId = getCurrentTimeInSec(); - - auto jsonPrinter = dynamic_cast(m_sinkContract->getPrinter("json")); - - m_jsonPrinter = make_unique(jsonPrinter->getJsonVersion()); - - m_printer = std::make_unique(jsonPrinter->getJsonVersion()); - - GetOptions(config, m_options, options); - AddOptions(config, m_options, - {{configuration::ProbeTopic, string()}, - {configuration::MqttCaCert, string()}, - {configuration::MqttPrivateKey, string()}, - {configuration::MqttCert, string()}, - {configuration::MqttClientId, string()}, - {configuration::MqttUserName, string()}, - {configuration::MqttPassword, string()}, - {configuration::MqttPort, int()}, - {configuration::MqttXPath, string()}, - {configuration::MqttRetain, bool()}, - {configuration::MqttQOS, string()}, - {configuration::MqttHost, string()}}); - AddDefaultedOptions( - config, m_options, - {{configuration::MqttHost, "127.0.0.1"s}, - {configuration::DeviceTopic, "MTConnect/Probe/[device]"s}, - {configuration::AssetTopic, "MTConnect/Asset/[device]"s}, - {configuration::MqttLastWillTopic, "MTConnect/Probe/[device]/Availability"s}, - {configuration::CurrentTopic, "MTConnect/Current/[device]"s}, - {configuration::SampleTopic, "MTConnect/Sample/[device]"s}, - {configuration::MqttCurrentInterval, 10000ms}, - {configuration::MqttSampleInterval, 500ms}, - {configuration::MqttSampleCount, 1000}, - {configuration::MqttTls, false}}); - - int maxTopicDepth {GetOption(options, configuration::MqttMaxTopicDepth).value_or(7)}; - - m_deviceTopic = GetOption(m_options, configuration::ProbeTopic) - .value_or(get(m_options[configuration::DeviceTopic])); - m_assetTopic = getTopic(configuration::AssetTopic, maxTopicDepth); - m_currentTopic = getTopic(configuration::CurrentTopic, maxTopicDepth); - m_sampleTopic = getTopic(configuration::SampleTopic, maxTopicDepth); - - m_currentInterval = *GetOption(m_options, configuration::MqttCurrentInterval); - m_sampleInterval = *GetOption(m_options, configuration::MqttSampleInterval); - - m_sampleCount = *GetOption(m_options, configuration::MqttSampleCount); - - if (!HasOption(m_options, configuration::MqttPort)) - { - if (HasOption(m_options, configuration::Port)) - { - m_options[configuration::MqttPort] = m_options[configuration::Port]; - } - else - { - m_options[configuration::MqttPort] = 1883; - } - } - - if (!HasOption(m_options, configuration::MqttHost) && - HasOption(m_options, configuration::Host)) - { - m_options[configuration::MqttHost] = m_options[configuration::Host]; - } - - auto retain = GetOption(m_options, configuration::MqttRetain); - if (retain) - m_retain = *retain; - - auto qoso = GetOption(m_options, configuration::MqttQOS); - - if (qoso) - { - auto qos = *qoso; - if (qos == "at_most_once") - m_qos = MqttClient::QOS::at_most_once; - else if (qos == "at_least_once") - m_qos = MqttClient::QOS::at_least_once; - else if (qos == "exactly_once") - m_qos = MqttClient::QOS::exactly_once; - else - LOG(warning) << "Invalid QOS for MQTT Client: " << qos - << ", must be at_most_once, at_least_once, or exactly_once"; - } - } - - void Mqtt2Service::start() - { - if (!m_client) - { - auto clientHandler = make_unique(); - clientHandler->m_connected = [this](shared_ptr client) { - // Publish latest devices, assets, and observations - auto &circ = m_sinkContract->getCircularBuffer(); - std::lock_guard lock(circ); - client->connectComplete(); - - client->publish(m_lastWillTopic, "AVAILABLE"); - pubishInitialContent(); - }; - - auto agentDevice = m_sinkContract->getDeviceByName("Agent"); - auto lwtTopic = get(m_options[configuration::MqttLastWillTopic]); - m_lastWillTopic = formatTopic(lwtTopic, agentDevice, "Agent"); - - if (IsOptionSet(m_options, configuration::MqttTls)) - { - m_client = make_shared(m_context, m_options, std::move(clientHandler), - m_lastWillTopic, "UNAVAILABLE"s); - } - else - { - m_client = make_shared(m_context, m_options, std::move(clientHandler), - m_lastWillTopic, "UNAVAILABLE"s); - } - } - m_client->start(); - } - - void Mqtt2Service::stop() - { - // stop client side - if (m_client) - m_client->stop(); - - m_currentTimer.cancel(); - } - - struct AsyncSample : public observation::AsyncObserver - { - AsyncSample(boost::asio::io_context::strand &strand, - mtconnect::buffer::CircularBuffer &buffer, FilterSet &&filter, - std::chrono::milliseconds interval, std::chrono::milliseconds heartbeat, - std::shared_ptr client, DevicePtr device) - : observation::AsyncObserver(strand, buffer, std::move(filter), interval, heartbeat), - m_device(device), - m_client(client) - {} - - void fail(boost::beast::http::status status, const std::string &message) override - { - LOG(error) << "MQTT Sample Failed: " << message; - } - - bool isRunning() override - { - if (m_sink.expired()) - return false; - - auto client = m_client.lock(); - return client && client->isRunning() && client->isConnected(); - } - - bool cancel() override - { - return true; - } - - DevicePtr m_device; - std::weak_ptr m_client; - std::weak_ptr - m_sink; //! weak shared pointer to the sink. handles shutdown timer race - }; - - void Mqtt2Service::pubishInitialContent() - { - using std::placeholders::_1; - for (auto &dev : m_sinkContract->getDevices()) - { - publish(dev); - - AssetList list; - m_sinkContract->getAssetStorage()->getAssets(list, 100000, true, *(dev->getUuid())); - for (auto &asset : list) - { - publish(asset); - } - } - - auto seq = publishCurrent(boost::system::error_code {}); - for (auto &dev : m_sinkContract->getDevices()) - { - FilterSet filterSet { filterForDevice(dev) }; - auto sampler = - make_shared(m_strand, m_sinkContract->getCircularBuffer(), - std::move(filterSet), m_sampleInterval, 600s, m_client, dev); - sampler->m_sink = getptr(); - sampler->m_handler = boost::bind(&Mqtt2Service::publishSample, this, _1); - sampler->observe(seq, [this](const std::string &id) { - return m_sinkContract->getDataItemById(id).get(); - }); - publishSample(sampler); - } - } - - /// @brief publish sample when observations arrive. - SequenceNumber_t Mqtt2Service::publishSample( - std::shared_ptr observer) - { - auto sampler = std::dynamic_pointer_cast(observer); - auto topic = formatTopic(m_sampleTopic, sampler->m_device); - LOG(debug) << "Publishing sample for: " << topic; - - std::unique_ptr observations; - SequenceNumber_t end {0}; - std::string doc; - SequenceNumber_t firstSeq, lastSeq; - - { - auto &buffer = m_sinkContract->getCircularBuffer(); - std::lock_guard lock(buffer); - - lastSeq = buffer.getSequence() - 1; - observations = - buffer.getObservations(m_sampleCount, sampler->getFilter(), sampler->getSequence(), - nullopt, end, firstSeq, observer->m_endOfBuffer); - } - - doc = m_printer->printSample(m_instanceId, - m_sinkContract->getCircularBuffer().getBufferSize(), end, - firstSeq, lastSeq, *observations, false); - - m_client->asyncPublish( - topic, doc, - [sampler, topic](std::error_code ec) { - if (!ec) - { - sampler->handlerCompleted(); - } - else - { - LOG(warning) << "Async publish failed for " << topic << ": " << ec.message(); - } - }, - m_retain, m_qos); - - return end; - } - - SequenceNumber_t Mqtt2Service::publishCurrent(boost::system::error_code ec) - { - SequenceNumber_t firstSeq, seq = 0; - - if (ec) - { - LOG(warning) << "Mqtt2Service::publishCurrent: " << ec.message(); - return 0; - } - - if (!m_client->isRunning() || !m_client->isConnected()) - { - LOG(warning) << "Mqtt2Service::publishCurrent: client stopped"; - return 0; - } - - for (auto &device : m_sinkContract->getDevices()) - { - auto topic = formatTopic(m_currentTopic, device); - LOG(debug) << "Publishing current for: " << topic; - - ObservationList observations; - auto filterSet = filterForDevice(device); - - { - auto &buffer = m_sinkContract->getCircularBuffer(); - std::lock_guard lock(buffer); - - firstSeq = buffer.getFirstSequence(); - seq = buffer.getSequence(); - m_sinkContract->getCircularBuffer().getLatest().getObservations(observations, - filterSet); - } - - auto doc = m_printer->printSample(m_instanceId, - m_sinkContract->getCircularBuffer().getBufferSize(), - seq, firstSeq, seq - 1, observations); - - m_client->publish(topic, doc, m_retain, m_qos); - } - - using std::placeholders::_1; - m_currentTimer.expires_after(m_currentInterval); - m_currentTimer.async_wait(boost::asio::bind_executor( - m_strand, boost::bind(&Mqtt2Service::publishCurrent, this, _1))); - - return seq; - } - - bool Mqtt2Service::publish(observation::ObservationPtr &observation) - { - // Since we are doing periodic publishing, there is nothing to do here. - return true; - } - - bool Mqtt2Service::publish(device_model::DevicePtr device) - { - m_filters.clear(); - - auto topic = formatTopic(m_deviceTopic, device); - auto doc = m_jsonPrinter->print(device); - - stringstream buffer; - buffer << doc; - - if (m_client) - m_client->publish(topic, buffer.str(), m_retain, m_qos); - - return true; - } - - bool Mqtt2Service::publish(asset::AssetPtr asset) - { - auto uuid = asset->getDeviceUuid(); - DevicePtr dev; - if (uuid) - dev = m_sinkContract->findDeviceByUUIDorName(*uuid); - auto topic = formatTopic(m_assetTopic, dev); - if (topic.back() != '/') - topic.append("/"); - topic.append(asset->getAssetId()); - - LOG(debug) << "Publishing Asset to topic: " << topic; - - asset::AssetList list {asset}; - auto doc = m_printer->printAssets( - m_instanceId, uint32_t(m_sinkContract->getAssetStorage()->getMaxAssets()), 1, list); - stringstream buffer; - buffer << doc; - - if (m_client) - m_client->publish(topic, buffer.str(), m_retain, m_qos); - - return true; - } - - // Register the service with the sink factory - void Mqtt2Service::registerFactory(SinkFactory &factory) - { - factory.registerFactory( - "Mqtt2Service", - [](const std::string &name, boost::asio::io_context &io, SinkContractPtr &&contract, - const ConfigOptions &options, const boost::property_tree::ptree &block) -> SinkPtr { - auto sink = std::make_shared(io, std::move(contract), options, block); - return sink; - }); - } - } // namespace mqtt_sink - } // namespace sink -} // namespace mtconnect diff --git a/src/mtconnect/sink/mqtt_sink/mqtt2_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt2_service.hpp deleted file mode 100644 index 366b60ffa..000000000 --- a/src/mtconnect/sink/mqtt_sink/mqtt2_service.hpp +++ /dev/null @@ -1,241 +0,0 @@ -// -// Copyright Copyright 2009-2023, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#pragma once - -#include "boost/asio/io_context.hpp" -#include - -#include - -#include "mtconnect/buffer/checkpoint.hpp" -#include "mtconnect/config.hpp" -#include "mtconnect/configuration/agent_config.hpp" -#include "mtconnect/entity/json_printer.hpp" -#include "mtconnect/mqtt/mqtt_client.hpp" -#include "mtconnect/observation/observation.hpp" -#include "mtconnect/printer//json_printer.hpp" -#include "mtconnect/printer/printer.hpp" -#include "mtconnect/printer/xml_printer_helper.hpp" -#include "mtconnect/sink/sink.hpp" -#include "mtconnect/utilities.hpp" - -using namespace std; -using namespace mtconnect; -using namespace mtconnect::entity; -using namespace mtconnect::mqtt_client; - -using json = nlohmann::json; - -namespace mtconnect { - class XmlPrinter; - - namespace sink { - - /// @brief MTConnect Mqtt implemention namespace - - namespace mqtt_sink { - - struct AsyncSample; - - class AGENT_LIB_API Mqtt2Service : public sink::Sink - { - // dynamic loading of sink - - public: - /// @brief Create a Mqtt Service sink - /// @param context the boost asio io_context - /// @param contract the Sink Contract from the agent - /// @param options configuration options - /// @param config additional configuration options if specified directly as a sink - Mqtt2Service(boost::asio::io_context &context, sink::SinkContractPtr &&contract, - const ConfigOptions &options, const boost::property_tree::ptree &config); - - ~Mqtt2Service() = default; - - // Sink Methods - /// @brief Start the Mqtt service - void start() override; - - /// @brief Shutdown the Mqtt service - void stop() override; - - /// @brief Receive an observation - /// - /// This does nothing since we are periodically publishing current and samples - /// - /// @param observation shared pointer to the observation - /// @return `true` if the publishing was successful - bool publish(observation::ObservationPtr &observation) override; - - /// @brief Receive an asset - /// @param asset shared point to the asset - /// @return `true` if successful - bool publish(asset::AssetPtr asset) override; - - /// @brief Receive a device - /// @param device shared pointer to the device - /// @return `true` if successful - bool publish(device_model::DevicePtr device) override; - - /// @brief Publsh all devices, assets, and begin async timer-based publishing - void pubishInitialContent(); - - /// @brief Publish a current using `CurrentInterval` option. - SequenceNumber_t publishCurrent(boost::system::error_code ec); - - /// @brief publish sample when observations arrive. - SequenceNumber_t publishSample(std::shared_ptr sampler); - - /// @brief Register the Sink factory to create this sink - /// @param factory - static void registerFactory(SinkFactory &factory); - - /// @brief gets a Mqtt Client - /// @return MqttClient - std::shared_ptr getClient() { return m_client; } - - /// @brief Mqtt Client is Connected or not - /// @return `true` when the client was connected - bool isConnected() { return m_client && m_client->isConnected(); } - - /// @name Retain and QOS flags - ///@{ - auto getRetain() { return m_retain; } - auto getQOS() { return m_qos; } - ///@} - - protected: - const FilterSet &filterForDevice(const DevicePtr &device) - { - auto filter = m_filters.find(*(device->getUuid())); - if (filter == m_filters.end()) - { - auto pos = m_filters.emplace(*(device->getUuid()), FilterSet()); - filter = pos.first; - auto &set = filter->second; - - auto xpath = GetOption(m_options, configuration::MqttXPath); - if (xpath) - { - try - { - m_sinkContract->getDataItemsForPath(device, xpath, set, nullopt); - } - catch (exception &e) - { - LOG(warning) << "MqttService: Invalid xpath '" << *xpath << - "', defaulting to all data items"; - } - - if (set.empty()) - { - LOG(warning) << "MqttService: Invalid xpath '" << *xpath << - "', defaulting to all data items"; - } - } - - if (set.empty()) - { - for (const auto &wdi : device->getDeviceDataItems()) - { - const auto di = wdi.lock(); - if (di) - set.insert(di->getId()); - } - } - } - return filter->second; - } - - std::string formatTopic(const std::string &topic, const DevicePtr device, - const std::string defaultUuid = "Unknown") - { - string uuid; - string formatted {topic}; - if (!device) - uuid = defaultUuid; - else - { - uuid = *(device->getUuid()); - if (std::dynamic_pointer_cast(device)) - { - uuid.insert(0, "Agent_"); - } - } - - if (formatted.find("[device]") == std::string::npos) - { - if (formatted.back() != '/') - formatted.append("/"); - formatted.append(uuid); - } - else - { - boost::replace_all(formatted, "[device]", uuid); - } - return formatted; - } - - std::string getTopic(const std::string &option, int maxTopicDepth) - { - auto topic {get(m_options[option])}; - auto depth = std::count(topic.begin(), topic.end(), '/'); - - if (depth > maxTopicDepth) - LOG(warning) << "Mqtt Option " << option - << " exceeds maximum number of levels: " << maxTopicDepth; - - return topic; - } - - protected: - std::string m_deviceTopic; //! Device topic prefix - std::string m_assetTopic; //! Asset topic prefix - std::string m_currentTopic; //! Current topic prefix - std::string m_sampleTopic; //! Sample topic prefix - std::string m_lastWillTopic; //! Topic to publish the last will when disconnected - - std::chrono::milliseconds m_currentInterval; //! Interval in ms to update current - std::chrono::milliseconds m_sampleInterval; //! min interval in ms to update sample - - uint64_t m_instanceId; - - boost::asio::io_context &m_context; - boost::asio::io_context::strand m_strand; - - ConfigOptions m_options; - - std::unique_ptr m_jsonPrinter; - std::unique_ptr m_printer; - - std::shared_ptr m_client; - boost::asio::steady_timer m_currentTimer; - int m_sampleCount; //! Timer for current requests - - std::map m_filters; - std::map> m_samplers; - - bool m_retain {true}; - MqttClient::QOS m_qos {MqttClient::QOS::at_least_once}; - - // For XPath - - }; - } // namespace mqtt_sink - } // namespace sink -} // namespace mtconnect diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp new file mode 100644 index 000000000..46aea8a12 --- /dev/null +++ b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp @@ -0,0 +1,197 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "mqtt_legacy_service.hpp" + +#include "mtconnect/configuration/config_options.hpp" +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/entity/factory.hpp" +#include "mtconnect/entity/json_parser.hpp" +#include "mtconnect/mqtt/mqtt_client_impl.hpp" +#include "mtconnect/printer/json_printer.hpp" + +using ptree = boost::property_tree::ptree; + +using namespace std; +using namespace mtconnect::asset; + +namespace asio = boost::asio; +namespace config = ::mtconnect::configuration; + +namespace mtconnect { + namespace sink { + namespace mqtt_sink { + // get obeservation in + // create a json printer + // call print + + MqttLegacyService::MqttLegacyService(boost::asio::io_context &context, + sink::SinkContractPtr &&contract, + const ConfigOptions &options, const ptree &config) + : Sink("MqttLegacyService", std::move(contract)), m_context(context), m_options(options) + { + auto jsonPrinter = dynamic_cast(m_sinkContract->getPrinter("json")); + m_jsonPrinter = make_unique(jsonPrinter->getJsonVersion()); + + GetOptions(config, m_options, options); + AddOptions(config, m_options, + {{configuration::ProbeTopic, string()}, + {configuration::MqttCaCert, string()}, + {configuration::MqttPrivateKey, string()}, + {configuration::MqttCert, string()}, + {configuration::MqttUserName, string()}, + {configuration::MqttPassword, string()}, + {configuration::MqttClientId, string()}}); + AddDefaultedOptions(config, m_options, + {{configuration::MqttHost, "127.0.0.1"s}, + {configuration::DeviceTopic, "MTConnect/Device/"s}, + {configuration::AssetTopic, "MTConnect/Asset/"s}, + {configuration::ObservationTopic, "MTConnect/Observation/"s}, + {configuration::MqttPort, 1883}, + {configuration::MqttTls, false}}); + + auto clientHandler = make_unique(); + clientHandler->m_connected = [this](shared_ptr client) { + // Publish latest devices, assets, and observations + auto &circ = m_sinkContract->getCircularBuffer(); + std::lock_guard lock(circ); + client->connectComplete(); + + for (auto &dev : m_sinkContract->getDevices()) + { + publish(dev); + } + + auto obsList {circ.getLatest().getObservations()}; + for (auto &obs : obsList) + { + observation::ObservationPtr p {obs.second}; + publish(p); + } + + AssetList list; + m_sinkContract->getAssetStorage()->getAssets(list, 100000); + for (auto &asset : list) + { + publish(asset); + } + }; + + m_devicePrefix = GetOption(m_options, configuration::ProbeTopic) + .value_or(get(m_options[configuration::DeviceTopic])); + m_assetPrefix = get(m_options[configuration::AssetTopic]); + m_observationPrefix = get(m_options[configuration::ObservationTopic]); + + if (IsOptionSet(m_options, configuration::MqttTls)) + { + m_client = make_shared(m_context, m_options, std::move(clientHandler)); + } + else + { + m_client = make_shared(m_context, m_options, std::move(clientHandler)); + } + } + + void MqttLegacyService::start() + { + // mqtt client side not a server side... + if (!m_client) + return; + + m_client->start(); + } + + void MqttLegacyService::stop() + { + // stop client side + if (m_client) + m_client->stop(); + } + + std::shared_ptr MqttLegacyService::getClient() { return m_client; } + + bool MqttLegacyService::publish(observation::ObservationPtr &observation) + { + // get the data item from observation + if (observation->isOrphan()) + return false; + + DataItemPtr dataItem = observation->getDataItem(); + + auto topic = m_observationPrefix + dataItem->getTopic(); // client asyn topic + auto content = dataItem->getTopicName(); // client asyn content + + // We may want to use the observation from the checkpoint. + string doc; + if (observation->getDataItem()->isCondition()) + { + doc = m_jsonPrinter->print(observation); + } + else + { + doc = m_jsonPrinter->printEntity(observation); + } + + if (m_client) + m_client->publish(topic, doc); + + return true; + } + + bool MqttLegacyService::publish(device_model::DevicePtr device) + { + auto topic = m_devicePrefix + *device->getUuid(); + auto doc = m_jsonPrinter->print(device); + + stringstream buffer; + buffer << doc; + + if (m_client) + m_client->publish(topic, buffer.str()); + + return true; + } + + bool MqttLegacyService::publish(asset::AssetPtr asset) + { + auto topic = m_assetPrefix + get(asset->getIdentity()); + auto doc = m_jsonPrinter->print(asset); + + stringstream buffer; + buffer << doc; + + if (m_client) + m_client->publish(topic, buffer.str()); + + return true; + } + + // Register the service with the sink factory + void MqttLegacyService::registerFactory(SinkFactory &factory) + { + factory.registerFactory( + "MqttLegacyService", + [](const std::string &name, boost::asio::io_context &io, SinkContractPtr &&contract, + const ConfigOptions &options, const boost::property_tree::ptree &block) -> SinkPtr { + auto sink = + std::make_shared(io, std::move(contract), options, block); + return sink; + }); + } + } // namespace mqtt_sink + } // namespace sink +} // namespace mtconnect diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp new file mode 100644 index 000000000..ab84d97d5 --- /dev/null +++ b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp @@ -0,0 +1,107 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include "boost/asio/io_context.hpp" +#include + +#include "mtconnect/buffer/checkpoint.hpp" +#include "mtconnect/config.hpp" +#include "mtconnect/configuration/agent_config.hpp" +#include "mtconnect/entity/json_printer.hpp" +#include "mtconnect/mqtt/mqtt_client.hpp" +#include "mtconnect/observation/observation.hpp" +#include "mtconnect/printer/printer.hpp" +#include "mtconnect/printer/xml_printer_helper.hpp" +#include "mtconnect/sink/sink.hpp" +#include "mtconnect/utilities.hpp" + +using namespace std; +using namespace mtconnect::entity; +using namespace mtconnect::mqtt_client; + +namespace mtconnect { + class XmlPrinter; + + namespace sink { + + /// @brief MTConnect Mqtt implemention namespace + + namespace mqtt_sink { + class AGENT_LIB_API MqttLegacyService : public sink::Sink + { + // dynamic loading of sink + + public: + /// @brief Create a Mqtt Service sink + /// @param context the boost asio io_context + /// @param contract the Sink Contract from the agent + /// @param options configuration options + /// @param config additional configuration options if specified directly as a sink + MqttLegacyService(boost::asio::io_context &context, sink::SinkContractPtr &&contract, + const ConfigOptions &options, const boost::property_tree::ptree &config); + + ~MqttLegacyService() = default; + + // Sink Methods + /// @brief Start the Mqtt service + void start() override; + + /// @brief Shutdown the Mqtt service + void stop() override; + + /// @brief Receive an observation + /// @param observation shared pointer to the observation + /// @return `true` if the publishing was successful + bool publish(observation::ObservationPtr &observation) override; + + /// @brief Receive an asset + /// @param asset shared point to the asset + /// @return `true` if successful + bool publish(asset::AssetPtr asset) override; + + /// @brief Receive a device + /// @param device shared pointer to the device + /// @return `true` if successful + bool publish(device_model::DevicePtr device) override; + + /// @brief Register the Sink factory to create this sink + /// @param factory + static void registerFactory(SinkFactory &factory); + + /// @brief gets a Mqtt Client + /// @return MqttClient + std::shared_ptr getClient(); + + /// @brief Mqtt Client is Connected or not + /// @return `true` when the client was connected + bool isConnected() { return m_client && m_client->isConnected(); } + + protected: + std::string m_devicePrefix; + std::string m_assetPrefix; + std::string m_observationPrefix; + + boost::asio::io_context &m_context; + ConfigOptions m_options; + std::unique_ptr m_jsonPrinter; + std::shared_ptr m_client; + }; + } // namespace mqtt_sink + } // namespace sink +} // namespace mtconnect diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp index b28b72d0f..7c17edbfd 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2023, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,6 +17,8 @@ #include "mqtt_service.hpp" +#include + #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/entity/entity.hpp" #include "mtconnect/entity/factory.hpp" @@ -25,8 +27,10 @@ #include "mtconnect/printer/json_printer.hpp" using ptree = boost::property_tree::ptree; +using json = nlohmann::json; using namespace std; +using namespace mtconnect; using namespace mtconnect::asset; namespace asio = boost::asio; @@ -41,119 +45,264 @@ namespace mtconnect { MqttService::MqttService(boost::asio::io_context &context, sink::SinkContractPtr &&contract, const ConfigOptions &options, const ptree &config) - : Sink("MqttService", std::move(contract)), m_context(context), m_options(options) + : Sink("MqttService", std::move(contract)), + m_context(context), + m_strand(context), + m_options(options), + m_currentTimer(context) { + // Unique id number for agent instance + m_instanceId = getCurrentTimeInSec(); + auto jsonPrinter = dynamic_cast(m_sinkContract->getPrinter("json")); + m_jsonPrinter = make_unique(jsonPrinter->getJsonVersion()); + m_printer = std::make_unique(jsonPrinter->getJsonVersion()); + GetOptions(config, m_options, options); AddOptions(config, m_options, {{configuration::ProbeTopic, string()}, {configuration::MqttCaCert, string()}, {configuration::MqttPrivateKey, string()}, {configuration::MqttCert, string()}, + {configuration::MqttClientId, string()}, {configuration::MqttUserName, string()}, - {configuration::MqttPassword, string()}, - {configuration::MqttClientId, string()}}); - AddDefaultedOptions(config, m_options, - {{configuration::MqttHost, "127.0.0.1"s}, - {configuration::DeviceTopic, "MTConnect/Device/"s}, - {configuration::AssetTopic, "MTConnect/Asset/"s}, - {configuration::ObservationTopic, "MTConnect/Observation/"s}, - {configuration::MqttPort, 1883}, - {configuration::MqttTls, false}}); - - auto clientHandler = make_unique(); - clientHandler->m_connected = [this](shared_ptr client) { - // Publish latest devices, assets, and observations - auto &circ = m_sinkContract->getCircularBuffer(); - std::lock_guard lock(circ); - client->connectComplete(); - - for (auto &dev : m_sinkContract->getDevices()) + {configuration::MqttPassword, string()}}); + AddDefaultedOptions( + config, m_options, + {{configuration::MqttHost, "127.0.0.1"s}, + {configuration::DeviceTopic, "MTConnect/Probe/[device]"s}, + {configuration::AssetTopic, "MTConnect/Asset/[device]"s}, + {configuration::MqttLastWillTopic, "MTConnect/Probe/[device]/Availability"s}, + {configuration::CurrentTopic, "MTConnect/Current/[device]"s}, + {configuration::SampleTopic, "MTConnect/Sample/[device]"s}, + {configuration::MqttCurrentInterval, 10000ms}, + {configuration::MqttSampleInterval, 500ms}, + {configuration::MqttSampleCount, 1000}, + {configuration::MqttPort, 1883}, + {configuration::MqttTls, false}}); + + int maxTopicDepth {GetOption(options, configuration::MqttMaxTopicDepth).value_or(7)}; + + m_deviceTopic = GetOption(m_options, configuration::ProbeTopic) + .value_or(get(m_options[configuration::DeviceTopic])); + m_assetTopic = getTopic(configuration::AssetTopic, maxTopicDepth); + m_currentTopic = getTopic(configuration::CurrentTopic, maxTopicDepth); + m_sampleTopic = getTopic(configuration::SampleTopic, maxTopicDepth); + + m_currentInterval = *GetOption(m_options, configuration::MqttCurrentInterval); + m_sampleInterval = *GetOption(m_options, configuration::MqttSampleInterval); + + m_sampleCount = *GetOption(m_options, configuration::MqttSampleCount); + } + + void MqttService::start() + { + if (!m_client) + { + auto clientHandler = make_unique(); + clientHandler->m_connected = [this](shared_ptr client) { + // Publish latest devices, assets, and observations + auto &circ = m_sinkContract->getCircularBuffer(); + std::lock_guard lock(circ); + client->connectComplete(); + + client->publish(m_lastWillTopic, "AVAILABLE"); + pubishInitialContent(); + }; + + auto agentDevice = m_sinkContract->getDeviceByName("Agent"); + auto lwtTopic = get(m_options[configuration::MqttLastWillTopic]); + m_lastWillTopic = formatTopic(lwtTopic, agentDevice, "Agent"); + + if (IsOptionSet(m_options, configuration::MqttTls)) { - publish(dev); + m_client = make_shared(m_context, m_options, std::move(clientHandler), + m_lastWillTopic, "UNAVAILABLE"s); } - - auto obsList {circ.getLatest().getObservations()}; - for (auto &obs : obsList) + else { - observation::ObservationPtr p {obs.second}; - publish(p); + m_client = make_shared(m_context, m_options, std::move(clientHandler), + m_lastWillTopic, "UNAVAILABLE"s); } + } + m_client->start(); + } + + void MqttService::stop() + { + // stop client side + if (m_client) + m_client->stop(); + + m_currentTimer.cancel(); + } + + struct AsyncSample : public observation::AsyncObserver + { + AsyncSample(boost::asio::io_context::strand &strand, + mtconnect::buffer::CircularBuffer &buffer, FilterSet &&filter, + std::chrono::milliseconds interval, std::chrono::milliseconds heartbeat, + std::shared_ptr client, DevicePtr device) + : observation::AsyncObserver(strand, buffer, std::move(filter), interval, heartbeat), + m_device(device), + m_client(client) + {} + + void fail(boost::beast::http::status status, const std::string &message) override + { + LOG(error) << "MQTT Sample Failed: " << message; + } + + bool isRunning() override + { + if (m_sink.expired()) + return false; + + auto client = m_client.lock(); + return client && client->isRunning() && client->isConnected(); + } + + bool cancel() override { return true; } + + DevicePtr m_device; + std::weak_ptr m_client; + std::weak_ptr + m_sink; //! weak shared pointer to the sink. handles shutdown timer race + }; + + void MqttService::pubishInitialContent() + { + using std::placeholders::_1; + for (auto &dev : m_sinkContract->getDevices()) + { + publish(dev); AssetList list; - m_sinkContract->getAssetStorage()->getAssets(list, 100000); + m_sinkContract->getAssetStorage()->getAssets(list, 100000, true, *(dev->getUuid())); for (auto &asset : list) { publish(asset); } - }; - - m_devicePrefix = GetOption(m_options, configuration::ProbeTopic) - .value_or(get(m_options[configuration::DeviceTopic])); - m_assetPrefix = get(m_options[configuration::AssetTopic]); - m_observationPrefix = get(m_options[configuration::ObservationTopic]); - - if (IsOptionSet(m_options, configuration::MqttTls)) - { - m_client = make_shared(m_context, m_options, std::move(clientHandler)); } - else + + auto seq = m_sinkContract->getCircularBuffer().getSequence(); + for (auto &dev : m_sinkContract->getDevices()) { - m_client = make_shared(m_context, m_options, std::move(clientHandler)); + FilterSet filterSet = filterForDevice(dev); + auto sampler = + make_shared(m_strand, m_sinkContract->getCircularBuffer(), + std::move(filterSet), m_sampleInterval, 600s, m_client, dev); + sampler->m_sink = getptr(); + sampler->m_handler = boost::bind(&MqttService::publishSample, this, _1); + sampler->observe(seq, [this](const std::string &id) { + return m_sinkContract->getDataItemById(id).get(); + }); + sampler->handlerCompleted(); } + + publishCurrent(boost::system::error_code {}); } - void MqttService::start() + /// @brief publish sample when observations arrive. + SequenceNumber_t MqttService::publishSample( + std::shared_ptr observer) { - // mqtt client side not a server side... - if (!m_client) - return; + auto sampler = std::dynamic_pointer_cast(observer); + auto topic = formatTopic(m_sampleTopic, sampler->m_device); + LOG(debug) << "Publishing sample for: " << topic; - m_client->start(); - } + std::unique_ptr observations; + SequenceNumber_t end {0}; + std::string doc; + SequenceNumber_t firstSeq, lastSeq; - void MqttService::stop() - { - // stop client side - if (m_client) - m_client->stop(); - } + { + auto &buffer = m_sinkContract->getCircularBuffer(); + std::lock_guard lock(buffer); - std::shared_ptr MqttService::getClient() { return m_client; } + lastSeq = buffer.getSequence() - 1; + observations = + buffer.getObservations(m_sampleCount, sampler->getFilter(), sampler->getSequence(), + nullopt, end, firstSeq, observer->m_endOfBuffer); + } - bool MqttService::publish(observation::ObservationPtr &observation) - { - // get the data item from observation - if (observation->isOrphan()) - return false; + doc = m_printer->printSample(m_instanceId, + m_sinkContract->getCircularBuffer().getBufferSize(), end, + firstSeq, lastSeq, *observations, false); - DataItemPtr dataItem = observation->getDataItem(); + m_client->asyncPublish(topic, doc, [sampler, topic](std::error_code ec) { + if (!ec) + { + sampler->handlerCompleted(); + } + else + { + LOG(warning) << "Async publish failed for " << topic << ": " << ec.message(); + } + }); - auto topic = m_observationPrefix + dataItem->getTopic(); // client asyn topic - auto content = dataItem->getTopicName(); // client asyn content + return end; + } - // We may want to use the observation from the checkpoint. - string doc; - if (observation->getDataItem()->isCondition()) + void MqttService::publishCurrent(boost::system::error_code ec) + { + if (ec) { - doc = m_jsonPrinter->print(observation); + LOG(warning) << "Mqtt2Service::publishCurrent: " << ec.message(); + return; } - else + + if (!m_client->isRunning() || !m_client->isConnected()) { - doc = m_jsonPrinter->printEntity(observation); + LOG(warning) << "Mqtt2Service::publishCurrent: client stopped"; + return; } - if (m_client) + for (auto &device : m_sinkContract->getDevices()) + { + auto topic = formatTopic(m_currentTopic, device); + LOG(debug) << "Publishing current for: " << topic; + + ObservationList observations; + SequenceNumber_t firstSeq, seq; + auto filterSet = filterForDevice(device); + + { + auto &buffer = m_sinkContract->getCircularBuffer(); + std::lock_guard lock(buffer); + + firstSeq = buffer.getFirstSequence(); + seq = buffer.getSequence(); + m_sinkContract->getCircularBuffer().getLatest().getObservations(observations, + filterSet); + } + + auto doc = m_printer->printSample(m_instanceId, + m_sinkContract->getCircularBuffer().getBufferSize(), + seq, firstSeq, seq - 1, observations); + m_client->publish(topic, doc); + } + + using std::placeholders::_1; + m_currentTimer.expires_after(m_currentInterval); + m_currentTimer.async_wait(boost::asio::bind_executor( + m_strand, boost::bind(&MqttService::publishCurrent, this, _1))); + } + bool MqttService::publish(observation::ObservationPtr &observation) + { + // Since we are doing periodic publishing, there is nothing to do here. return true; } bool MqttService::publish(device_model::DevicePtr device) { - auto topic = m_devicePrefix + *device->getUuid(); + m_filters.clear(); + + auto topic = formatTopic(m_deviceTopic, device); auto doc = m_jsonPrinter->print(device); stringstream buffer; @@ -167,7 +316,17 @@ namespace mtconnect { bool MqttService::publish(asset::AssetPtr asset) { - auto topic = m_assetPrefix + get(asset->getIdentity()); + auto uuid = asset->getDeviceUuid(); + DevicePtr dev; + if (uuid) + dev = m_sinkContract->findDeviceByUUIDorName(*uuid); + auto topic = formatTopic(m_assetTopic, dev); + if (topic.back() != '/') + topic.append("/"); + topic.append(asset->getAssetId()); + + LOG(debug) << "Publishing Asset to topic: " << topic; + auto doc = m_jsonPrinter->print(asset); stringstream buffer; diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp index e94d01f55..6cba52409 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp @@ -1,5 +1,5 @@ // -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// Copyright Copyright 2009-2023, AMT – The Association For Manufacturing Technology (“AMT”) // All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,21 +20,27 @@ #include "boost/asio/io_context.hpp" #include +#include + #include "mtconnect/buffer/checkpoint.hpp" #include "mtconnect/config.hpp" #include "mtconnect/configuration/agent_config.hpp" #include "mtconnect/entity/json_printer.hpp" #include "mtconnect/mqtt/mqtt_client.hpp" #include "mtconnect/observation/observation.hpp" +#include "mtconnect/printer//json_printer.hpp" #include "mtconnect/printer/printer.hpp" #include "mtconnect/printer/xml_printer_helper.hpp" #include "mtconnect/sink/sink.hpp" #include "mtconnect/utilities.hpp" using namespace std; +using namespace mtconnect; using namespace mtconnect::entity; using namespace mtconnect::mqtt_client; +using json = nlohmann::json; + namespace mtconnect { class XmlPrinter; @@ -43,6 +49,9 @@ namespace mtconnect { /// @brief MTConnect Mqtt implemention namespace namespace mqtt_sink { + + struct AsyncSample; + class AGENT_LIB_API MqttService : public sink::Sink { // dynamic loading of sink @@ -66,6 +75,9 @@ namespace mtconnect { void stop() override; /// @brief Receive an observation + /// + /// This does nothing since we are periodically publishing current and samples + /// /// @param observation shared pointer to the observation /// @return `true` if the publishing was successful bool publish(observation::ObservationPtr &observation) override; @@ -80,27 +92,113 @@ namespace mtconnect { /// @return `true` if successful bool publish(device_model::DevicePtr device) override; + /// @brief Publsh all devices, assets, and begin async timer-based publishing + void pubishInitialContent(); + + /// @brief Publish a current using `CurrentInterval` option. + void publishCurrent(boost::system::error_code ec); + + /// @brief publish sample when observations arrive. + SequenceNumber_t publishSample(std::shared_ptr sampler); + /// @brief Register the Sink factory to create this sink /// @param factory static void registerFactory(SinkFactory &factory); /// @brief gets a Mqtt Client /// @return MqttClient - std::shared_ptr getClient(); + std::shared_ptr getClient() { return m_client; } /// @brief Mqtt Client is Connected or not /// @return `true` when the client was connected bool isConnected() { return m_client && m_client->isConnected(); } protected: - std::string m_devicePrefix; - std::string m_assetPrefix; - std::string m_observationPrefix; + const FilterSet &filterForDevice(const DevicePtr &device) + { + auto filter = m_filters.find(*(device->getUuid())); + if (filter == m_filters.end()) + { + auto pos = m_filters.emplace(*(device->getUuid()), FilterSet()); + filter = pos.first; + auto &set = filter->second; + for (const auto &wdi : device->getDeviceDataItems()) + { + const auto di = wdi.lock(); + if (di) + set.insert(di->getId()); + } + } + return filter->second; + } + + std::string formatTopic(const std::string &topic, const DevicePtr device, + const std::string defaultUuid = "Unknown") + { + string uuid; + string formatted {topic}; + if (!device) + uuid = defaultUuid; + else + { + uuid = *(device->getUuid()); + if (std::dynamic_pointer_cast(device)) + { + uuid.insert(0, "Agent_"); + } + } + + if (formatted.find("[device]") == std::string::npos) + { + if (formatted.back() != '/') + formatted.append("/"); + formatted.append(uuid); + } + else + { + boost::replace_all(formatted, "[device]", uuid); + } + return formatted; + } + + std::string getTopic(const std::string &option, int maxTopicDepth) + { + auto topic {get(m_options[option])}; + auto depth = std::count(topic.begin(), topic.end(), '/'); + + if (depth > maxTopicDepth) + LOG(warning) << "Mqtt Option " << option + << " exceeds maximum number of levels: " << maxTopicDepth; + + return topic; + } + + protected: + std::string m_deviceTopic; //! Device topic prefix + std::string m_assetTopic; //! Asset topic prefix + std::string m_currentTopic; //! Current topic prefix + std::string m_sampleTopic; //! Sample topic prefix + std::string m_lastWillTopic; //! Topic to publish the last will when disconnected + + std::chrono::milliseconds m_currentInterval; //! Interval in ms to update current + std::chrono::milliseconds m_sampleInterval; //! min interval in ms to update sample + + uint64_t m_instanceId; boost::asio::io_context &m_context; + boost::asio::io_context::strand m_strand; + ConfigOptions m_options; + std::unique_ptr m_jsonPrinter; + std::unique_ptr m_printer; + std::shared_ptr m_client; + boost::asio::steady_timer m_currentTimer; + int m_sampleCount; //! Timer for current requests + + std::map m_filters; + std::map> m_samplers; }; } // namespace mqtt_sink } // namespace sink diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index c8c3fbcfb..2361894b4 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -115,7 +115,8 @@ namespace mtconnect { {"pretty", QUERY, "Instructs the result to be pretty printed"}, {"format", QUERY, "The format of the response document: 'xml' or 'json'"}, {"heartbeat", QUERY, - "Time in ms between publishing a empty document when no data has changed"}}); + "Time in ms between publishing a empty document when no data has changed"}, + {"requestId", PATH, "webservice request id"}}); createProbeRoutings(); createCurrentRoutings(); @@ -763,6 +764,11 @@ namespace mtconnect { return true; }; + auto cancelHandler = [&](SessionPtr session, RequestPtr request) -> bool { + auto requestId = *request->parameter("requestId"); + return session->cancelRequest(requestId); + }; + string qp( "path={string}&from={unsigned_integer}&" "interval={integer}&count={integer:100}&" @@ -780,6 +786,9 @@ namespace mtconnect { "optionally filtered by the `path` and starting at `from`. By default, from is " "the first available observation known to the agent") .command("sample"); + m_server + ->addRouting({boost::beast::http::verb::get, "/cancel/requestId={string}", cancelHandler}) + .document("MTConnect WebServices Cancel Stream", "Cancels a streaming sample request"); } void RestService::createPutObservationRoutings() @@ -963,11 +972,11 @@ namespace mtconnect { return server->isRunning(); } } - + bool cancel() override { observation::AsyncObserver::cancel(); - m_session.reset(); + m_session.reset(); return true; } @@ -979,7 +988,6 @@ namespace mtconnect { rest_sink::SessionPtr m_session; ofstream m_log; bool m_pretty {false}; - std::optional m_requestId; }; void RestService::streamSampleRequest(rest_sink::SessionPtr session, const Printer *printer, @@ -1022,7 +1030,7 @@ namespace mtconnect { asyncResponse->m_printer = printer; asyncResponse->m_sink = getptr(); asyncResponse->m_pretty = pretty; - asyncResponse->m_requestId = requestId; + asyncResponse->setRequestId(requestId); session->addObserver(asyncResponse); if (m_logStreamData) @@ -1067,7 +1075,7 @@ namespace mtconnect { string content = fetchSampleData(asyncResponse->m_printer, asyncResponse->getFilter(), asyncResponse->m_count, from, nullopt, end, asyncObserver->m_endOfBuffer, asyncResponse->m_pretty, - asyncResponse->m_requestId); + asyncResponse->getRequestId()); if (m_logStreamData) asyncResponse->m_log << content << endl; @@ -1076,7 +1084,7 @@ namespace mtconnect { content, asio::bind_executor(m_strand, boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), - asyncResponse->m_requestId); + asyncResponse->getRequestId()); return end; } diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index 8d3f76412..ba690894f 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -118,13 +118,27 @@ namespace mtconnect::sink::rest_sink { m_message = msg; m_unauthorized = true; } - + /// @brief Add an observer to the list for cleanup later. void addObserver(std::weak_ptr observer) { m_observers.push_back(observer); } + bool cancelRequest(const std::string &requestId) + { + for (auto &obs : m_observers) + { + auto pobs = obs.lock(); + if (pobs && pobs->getRequestId() == requestId) + { + pobs->cancel(); + return true; + } + } + return false; + } + protected: Dispatch m_dispatch; ErrorFunction m_errorFunction; diff --git a/src/mtconnect/sink/rest_sink/session_impl.cpp b/src/mtconnect/sink/rest_sink/session_impl.cpp index f1eeef2e5..cdd04d2e8 100644 --- a/src/mtconnect/sink/rest_sink/session_impl.cpp +++ b/src/mtconnect/sink/rest_sink/session_impl.cpp @@ -527,7 +527,7 @@ namespace mtconnect::sink::rest_sink { if (!m_closing) { m_closing = true; - + // Release all references from observers. for (auto obs : m_observers) { @@ -538,7 +538,6 @@ namespace mtconnect::sink::rest_sink { } } - // Set the timeout. beast::get_lowest_layer(m_stream).expires_after(std::chrono::seconds(30)); diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index e38b0c4dd..f06b916c8 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -96,15 +96,15 @@ namespace mtconnect::sink::rest_sink { beast::bind_front_handler(&WebsocketSession::onAccept, derived().shared_ptr()))); } - + void close() override { NAMED_SCOPE("PlainWebsocketSession::close"); if (!m_isOpen) return; - + auto ptr = derived().shared_ptr(); - + m_request.reset(); m_requests.clear(); for (auto obs : m_observers) @@ -116,7 +116,7 @@ namespace mtconnect::sink::rest_sink { } } closeStream(); - + m_isOpen = false; } @@ -170,12 +170,12 @@ namespace mtconnect::sink::rest_sink { std::optional requestId = std::nullopt) override { NAMED_SCOPE("WebsocketSession::writeChunk"); - + if (!derived().stream().is_open()) { return; } - + if (requestId) { LOG(trace) << "Waiting for mutex"; @@ -204,7 +204,7 @@ namespace mtconnect::sink::rest_sink { fail(status::internal_server_error, "Error occurred in accpet", ec); return; } - + m_isOpen = true; derived().stream().async_read( @@ -311,7 +311,7 @@ namespace mtconnect::sink::rest_sink { using namespace rapidjson; using namespace std; - + if (len == 0) { LOG(trace) << "Empty message received"; @@ -435,7 +435,7 @@ namespace mtconnect::sink::rest_sink { std::mutex m_mutex; std::atomic_bool m_busy; std::deque m_messageQueue; - bool m_isOpen { false }; + bool m_isOpen {false}; }; template @@ -453,8 +453,8 @@ namespace mtconnect::sink::rest_sink { { beast::get_lowest_layer(m_stream).expires_never(); } - ~PlainWebsocketSession() - { + ~PlainWebsocketSession() + { if (m_isOpen) close(); } @@ -492,12 +492,12 @@ namespace mtconnect::sink::rest_sink { { beast::get_lowest_layer(m_stream).expires_never(); } - ~TlsWebsocketSession() + ~TlsWebsocketSession() { if (m_isOpen) close(); } - + auto &stream() { return m_stream; } auto getExecutor() { return m_stream.get_executor(); } diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index 08a4e1ffd..ec5961013 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -249,8 +249,8 @@ add_agent_test(tls_http_server FALSE sink/rest_sink TRUE) add_agent_test(routing FALSE sink/rest_sink) add_agent_test(mqtt_isolated FALSE mqtt_isolated TRUE) +add_agent_test(mqtt_legacy_sink FALSE sink/mqtt_legacy_sink TRUE) add_agent_test(mqtt_sink FALSE sink/mqtt_sink TRUE) -add_agent_test(mqtt_sink_2 FALSE sink/mqtt_sink_2 TRUE) add_agent_test(json_printer_asset TRUE json) add_agent_test(json_printer_error TRUE json) diff --git a/test_package/agent_test_helper.hpp b/test_package/agent_test_helper.hpp index a0f93a0bb..4d16eb475 100644 --- a/test_package/agent_test_helper.hpp +++ b/test_package/agent_test_helper.hpp @@ -29,7 +29,7 @@ #include "mtconnect/configuration/agent_config.hpp" #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/pipeline/pipeline.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt2_service.hpp" +#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" #include "mtconnect/sink/mqtt_sink/mqtt_service.hpp" #include "mtconnect/sink/rest_sink/response.hpp" #include "mtconnect/sink/rest_sink/rest_service.hpp" @@ -124,8 +124,8 @@ class AgentTestHelper ~AgentTestHelper() { + m_mqttLegacyService.reset(); m_mqttService.reset(); - m_mqtt2Service.reset(); m_restService.reset(); m_adapter.reset(); if (m_agent) @@ -171,21 +171,21 @@ class AgentTestHelper return rest; } - std::shared_ptr getMqttService() + std::shared_ptr getMqttLegacyService() { using namespace mtconnect; - sink::SinkPtr sink = m_agent->findSink("MqttService"); - std::shared_ptr mqtt = - std::dynamic_pointer_cast(sink); + sink::SinkPtr sink = m_agent->findSink("MqttLegacyService"); + std::shared_ptr mqtt = + std::dynamic_pointer_cast(sink); return mqtt; } - std::shared_ptr getMqtt2Service() + std::shared_ptr getMqttService() { using namespace mtconnect; - sink::SinkPtr mqttSink = m_agent->findSink("Mqtt2Service"); - std::shared_ptr mqtt2 = - std::dynamic_pointer_cast(mqttSink); + sink::SinkPtr mqttSink = m_agent->findSink("MqttService"); + std::shared_ptr mqtt2 = + std::dynamic_pointer_cast(mqttSink); return mqtt2; } @@ -199,8 +199,8 @@ class AgentTestHelper using ptree = boost::property_tree::ptree; sink::rest_sink::RestService::registerFactory(m_sinkFactory); + sink::mqtt_sink::MqttLegacyService::registerFactory(m_sinkFactory); sink::mqtt_sink::MqttService::registerFactory(m_sinkFactory); - sink::mqtt_sink::Mqtt2Service::registerFactory(m_sinkFactory); source::adapter::shdr::ShdrAdapter::registerFactory(m_sourceFactory); ConfigOptions options = ops; @@ -232,24 +232,24 @@ class AgentTestHelper m_restService = std::dynamic_pointer_cast(sink); m_agent->addSink(m_restService); - if (HasOption(options, "MqttSink")) + if (HasOption(options, "MqttLegacySink")) { auto mqttContract = m_agent->makeSinkContract(); mqttContract->m_pipelineContext = m_context; - auto mqttsink = m_sinkFactory.make("MqttService", "MqttService", m_ioContext, + auto mqttsink = m_sinkFactory.make("MqttLegacyService", "MqttLegacyService", m_ioContext, std::move(mqttContract), options, ptree {}); - m_mqttService = std::dynamic_pointer_cast(mqttsink); - m_agent->addSink(m_mqttService); + m_mqttLegacyService = std::dynamic_pointer_cast(mqttsink); + m_agent->addSink(m_mqttLegacyService); } - if (HasOption(options, "Mqtt2Sink")) + if (HasOption(options, "MqttSink")) { auto mqttContract = m_agent->makeSinkContract(); mqttContract->m_pipelineContext = m_context; - auto mqtt2sink = m_sinkFactory.make("Mqtt2Service", "Mqtt2Service", m_ioContext, + auto mqtt2sink = m_sinkFactory.make("MqttService", "MqttService", m_ioContext, std::move(mqttContract), options, ptree {}); - m_mqtt2Service = std::dynamic_pointer_cast(mqtt2sink); - m_agent->addSink(m_mqtt2Service); + m_mqttService = std::dynamic_pointer_cast(mqtt2sink); + m_agent->addSink(m_mqttService); } m_agent->initialize(m_context); @@ -324,8 +324,8 @@ class AgentTestHelper mhttp::Server *m_server {nullptr}; std::shared_ptr m_context; std::shared_ptr m_adapter; + std::shared_ptr m_mqttLegacyService; std::shared_ptr m_mqttService; - std::shared_ptr m_mqtt2Service; std::shared_ptr m_restService; std::shared_ptr m_loopback; diff --git a/test_package/mqtt_isolated_test.cpp b/test_package/mqtt_isolated_test.cpp index 9789436c5..4e7cbc566 100644 --- a/test_package/mqtt_isolated_test.cpp +++ b/test_package/mqtt_isolated_test.cpp @@ -181,7 +181,7 @@ class MqttIsolatedUnitTest : public testing::Test std::unique_ptr m_jsonPrinter; std::shared_ptr m_server; std::shared_ptr m_client; - std::shared_ptr m_service; + std::shared_ptr m_service; std::unique_ptr m_agentTestHelper; uint16_t m_port {0}; }; diff --git a/test_package/mqtt_legacy_sink_test.cpp b/test_package/mqtt_legacy_sink_test.cpp new file mode 100644 index 000000000..4647c924e --- /dev/null +++ b/test_package/mqtt_legacy_sink_test.cpp @@ -0,0 +1,630 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +/// @file +/// Test MQTT 1 Service + +// Ensure that gtest is the first header otherwise Windows raises an error +#include +// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) + +#include + +#include + +#include "agent_test_helper.hpp" +#include "mtconnect/buffer/checkpoint.hpp" +#include "mtconnect/device_model/data_item/data_item.hpp" +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/entity/json_parser.hpp" +#include "mtconnect/mqtt/mqtt_client_impl.hpp" +#include "mtconnect/mqtt/mqtt_server_impl.hpp" +#include "mtconnect/printer//json_printer.hpp" +#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" + +using namespace std; +using namespace mtconnect; +using namespace mtconnect::device_model::data_item; +using namespace mtconnect::sink::mqtt_sink; +using namespace mtconnect::asset; +using namespace mtconnect::configuration; + +// main +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +using json = nlohmann::json; + +class MqttSinkTest : public testing::Test +{ +protected: + void SetUp() override + { + m_agentTestHelper = make_unique(); + m_jsonPrinter = std::make_unique(2, true); + } + + void TearDown() override + { + const auto agent = m_agentTestHelper->getAgent(); + if (agent) + { + m_agentTestHelper->getAgent()->stop(); + m_agentTestHelper->m_ioContext.run_for(100ms); + } + if (m_client) + { + m_client->stop(); + m_agentTestHelper->m_ioContext.run_for(100ms); + m_client.reset(); + } + if (m_server) + { + m_server->stop(); + m_agentTestHelper->m_ioContext.run_for(500ms); + m_server.reset(); + } + m_agentTestHelper.reset(); + m_jsonPrinter.reset(); + } + + void createAgent(std::string testFile = {}, ConfigOptions options = {}) + { + if (testFile == "") + testFile = "/samples/test_config.xml"; + + ConfigOptions opts(options); + MergeOptions(opts, {{"MqttLegacySink", true}, + {configuration::MqttPort, m_port}, + {configuration::MqttHost, "127.0.0.1"s}}); + m_agentTestHelper->createAgent(testFile, 8, 4, "2.0", 25, false, true, opts); + addAdapter(); + + m_agentTestHelper->getAgent()->start(); + } + + void createServer(const ConfigOptions &options) + { + using namespace mtconnect::configuration; + ConfigOptions opts(options); + MergeOptions(opts, {{ServerIp, "127.0.0.1"s}, + {MqttPort, 0}, + {MqttTls, false}, + {AutoAvailable, false}, + {RealTime, false}}); + + m_server = + make_shared(m_agentTestHelper->m_ioContext, opts); + } + + template + bool waitFor(const chrono::duration &time, function pred) + { + boost::asio::steady_timer timer(m_agentTestHelper->m_ioContext); + timer.expires_from_now(time); + bool timeout = false; + timer.async_wait([&timeout](boost::system::error_code ec) { + if (!ec) + { + timeout = true; + } + }); + + while (!timeout && !pred()) + { + m_agentTestHelper->m_ioContext.run_for(100ms); + } + timer.cancel(); + + return pred(); + } + + void startServer() + { + if (m_server) + { + bool start = m_server->start(); + if (start) + { + m_port = m_server->getPort(); + m_agentTestHelper->m_ioContext.run_for(500ms); + } + } + } + + void createClient(const ConfigOptions &options, unique_ptr &&handler) + { + ConfigOptions opts(options); + MergeOptions(opts, {{MqttHost, "127.0.0.1"s}, + {MqttPort, m_port}, + {MqttTls, false}, + {AutoAvailable, false}, + {RealTime, false}}); + m_client = make_shared(m_agentTestHelper->m_ioContext, + opts, std::move(handler)); + } + + bool startClient() + { + bool started = m_client && m_client->start(); + if (started) + { + return waitFor(5s, [this]() { return m_client->isConnected(); }); + } + return started; + } + + void addAdapter(ConfigOptions options = ConfigOptions {}) + { + m_agentTestHelper->addAdapter(options, "localhost", 0, + m_agentTestHelper->m_agent->getDefaultDevice()->getName()); + } + + std::unique_ptr m_jsonPrinter; + std::shared_ptr m_server; + std::shared_ptr m_client; + std::shared_ptr m_service; + std::unique_ptr m_agentTestHelper; + uint16_t m_port {0}; +}; + +TEST_F(MqttSinkTest, mqtt_sink_should_be_loaded_by_agent) +{ + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + + ASSERT_TRUE(service); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker) +{ + ConfigOptions options; + createServer(options); + startServer(); + + ASSERT_NE(0, m_port); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_with_UserNameandPassword) +{ + ConfigOptions options {{MqttUserName, "MQTT-SINK"s}, {MqttPassword, "mtconnect"s}}; + createServer(options); + startServer(); + + ASSERT_NE(0, m_port); + + createAgent("", options); + auto service = m_agentTestHelper->getMqttLegacyService(); + + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_without_UserNameandPassword) +{ + ConfigOptions options; + createServer(options); + startServer(); + + ASSERT_NE(0, m_port); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_device) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool gotDevice = false; + handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, + const std::string &topic, const std::string &payload) { + EXPECT_EQ("MTConnect/Device/000", topic); + + ErrorList list; + auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); + EXPECT_EQ(0, list.size()); + auto dev = dynamic_pointer_cast(ptr); + EXPECT_TRUE(dev); + EXPECT_EQ("LinuxCNC", dev->getComponentName()); + EXPECT_EQ("000", *dev->getUuid()); + + gotDevice = true; + }; + + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + m_client->subscribe("MTConnect/Device/000"); + + createAgent(); + + auto service = m_agentTestHelper->getMqttLegacyService(); + + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + + ASSERT_TRUE(waitFor(5s, [&gotDevice]() { return gotDevice; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Streams) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool foundLineDataItem = false; + handler->m_receive = [&foundLineDataItem](std::shared_ptr client, + const std::string &topic, const std::string &payload) { + EXPECT_EQ("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]", topic); + + auto jdoc = json::parse(payload); + string value = jdoc.at("/value"_json_pointer).get(); + EXPECT_EQ("204", value); + foundLineDataItem = true; + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + + m_client->subscribe("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]"); + m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); + + ASSERT_TRUE(waitFor(5s, [&foundLineDataItem]() { return foundLineDataItem; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Asset) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool gotControllerDataItem = false; + handler->m_receive = [&gotControllerDataItem](std::shared_ptr, + const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Asset/0001", topic); + auto jdoc = json::parse(payload); + string id = jdoc.at("/Part/assetId"_json_pointer).get(); + EXPECT_EQ("0001", id); + gotControllerDataItem = true; + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe("MTConnect/Asset/0001"); + + m_agentTestHelper->m_adapter->processData( + "2021-02-01T12:00:00Z|@ASSET@|@1|Part|TEST 1"); + + ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_RotaryMode) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool gotRotaryMode = false; + handler->m_receive = [&gotRotaryMode](std::shared_ptr, const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]", + topic); + auto jdoc = json::parse(payload); + + double v = jdoc.at("/value"_json_pointer).get(); + EXPECT_EQ(5000.0, v); + gotRotaryMode = true; + }; + + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe( + "MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]"); + + m_agentTestHelper->m_adapter->processData( + "2021-02-01T12:00:00Z|block|G01X00|Sspeed|5000|line|204"); + + ASSERT_TRUE(waitFor(5s, [&gotRotaryMode]() { return gotRotaryMode; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Dataset) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + entity::JsonParser parser; + auto handler = make_unique(); + bool gotControllerDataItem = false; + handler->m_receive = [&gotControllerDataItem](std::shared_ptr, + const std::string &topic, + const std::string &payload) { + EXPECT_EQ( + "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]", + topic); + auto jdoc = json::parse(payload); + auto id = jdoc.at("/value/a"_json_pointer).get(); + EXPECT_EQ(1, id); + gotControllerDataItem = true; + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + createAgent("/samples/data_set.xml"); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe( + "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]"); + + m_agentTestHelper->m_adapter->processData("TIME|vars|a=1 b=2 c=3"); + ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Table) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + entity::JsonParser parser; + auto handler = make_unique(); + bool gotControllerDataItem = false; + handler->m_receive = [&gotControllerDataItem](std::shared_ptr, + const std::string &topic, + const std::string &payload) { + EXPECT_EQ( + "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/WorkOffsetTable[wpo]", + topic); + auto jdoc = json::parse(payload); + + auto jValue = jdoc.at("/value"_json_pointer); + int count = 0; + if (jValue.is_object()) + { + for (auto &[key, value] : jValue.items()) + { + if (key == "G53.1" || key == "G53.2" || key == "G53.3") + { + for (auto &[subKey, subValue] : value.items()) + { + if (key == "G53.1" && ((subKey == "X" && subValue.get() == 1) || + (subKey == "Y" && subValue.get() == 2) || + (subKey == "Z" && subValue.get() == 3))) + { + count++; + } + else if (key == "G53.2" && ((subKey == "X" && subValue.get() == 4) || + (subKey == "Y" && subValue.get() == 5) || + (subKey == "Z" && subValue.get() == 6))) + { + count++; + } + else if (key == "G53.3" && ((subKey == "X" && subValue.get() == 7.0) || + (subKey == "Y" && subValue.get() == 8.0) || + (subKey == "Z" && subValue.get() == 9.0) || + (subKey == "U" && subValue.get() == 10.0))) + { + count++; + } + } + } + } + EXPECT_EQ(10, count); + gotControllerDataItem = true; + } + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + createAgent("/samples/data_set.xml"); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe( + "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/" + "WorkOffsetTable[wpo]"); + + m_agentTestHelper->m_adapter->processData( + "2021-02-01T12:00:00Z|wpo|G53.1={X=1.0 Y=2.0 Z=3.0} G53.2={X=4.0 Y=5.0 Z=6.0}" + "G53.3={X=7.0 Y=8.0 Z=9 U=10.0}"); + + ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Temperature) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool gotTemperature = false; + handler->m_receive = [&gotTemperature](std::shared_ptr, const std::string &topic, + const std::string &payload) { + EXPECT_EQ( + "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" + "Temperature[z_motor_temp]", + topic); + auto jdoc = json::parse(payload); + + auto value = jdoc.at("/value"_json_pointer).get(); + EXPECT_EQ(81.0, value); + gotTemperature = true; + }; + + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe( + "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" + "Temperature[z_motor_temp]"); + + m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|z_motor_temp|81"); + + ASSERT_TRUE(waitFor(5s, [&gotTemperature]() { return gotTemperature; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_LinearLoad) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + entity::JsonParser parser; + auto handler = make_unique(); + bool gotLinearLoad = false; + handler->m_receive = [&gotLinearLoad](std::shared_ptr, const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]", topic); + auto jdoc = json::parse(payload); + auto value = jdoc.at("/value"_json_pointer).get(); + EXPECT_EQ(50.0, value); + gotLinearLoad = true; + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]"); + + m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|Xload|50"); + ASSERT_TRUE(waitFor(5s, [&gotLinearLoad]() { return gotLinearLoad; })); +} + +TEST_F(MqttSinkTest, mqtt_sink_should_publish_DynamicCalibration) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + + entity::JsonParser parser; + + auto handler = make_unique(); + bool gotCalibration = false; + handler->m_receive = [this, &gotCalibration](std::shared_ptr, + const std::string &topic, + const std::string &payload) { + EXPECT_EQ( + "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]", + topic); + auto jdoc = json::parse(payload); + + auto value = jdoc.at("/value"_json_pointer); + ASSERT_TRUE(value.is_array()); + EXPECT_EQ(25, value.size()); + gotCalibration = true; + }; + + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + + createAgent(); + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + + m_client->subscribe( + "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]"); + + m_agentTestHelper->m_adapter->processData( + "2021-02-01T12:00:00Z|Xts|25|| 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 " + "5119 5119 5118 " + "5118 5117 5117 5119 5119 5118 5118 5118 5118 5118"); + + ASSERT_TRUE(waitFor(5s, [&gotCalibration]() { return gotCalibration; })); +} + +/// @test check if the condition includes the state as the key +TEST_F(MqttSinkTest, mqtt_should_publish_conditions_with_the_state_as_the_key) +{ + ConfigOptions options; + createServer(options); + startServer(); + ASSERT_NE(0, m_port); + entity::JsonParser parser; + auto handler = make_unique(); + bool gotCondition = false; + + handler->m_receive = [&gotCondition](std::shared_ptr, const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature", topic); + auto jdoc = json::parse(payload); + EXPECT_EQ("Temperature is too high", jdoc.at("/Fault/value"_json_pointer).get()); + EXPECT_EQ("X111", jdoc.at("/Fault/nativeCode"_json_pointer).get()); + EXPECT_EQ("BAD", jdoc.at("/Fault/nativeSeverity"_json_pointer).get()); + EXPECT_EQ("HIGH", jdoc.at("/Fault/qualifier"_json_pointer).get()); + EXPECT_EQ("TEMPERATURE", jdoc.at("/Fault/type"_json_pointer).get()); + + gotCondition = true; + }; + createClient(options, std::move(handler)); + ASSERT_TRUE(startClient()); + createAgent(); + + auto di = m_agentTestHelper->m_agent->getDataItemById("ctmp"); + ASSERT_TRUE(di); + ASSERT_EQ("000/Axes[Axes]/Rotary[C]/Condition/Temperature", di->getTopic()); + + auto service = m_agentTestHelper->getMqttLegacyService(); + ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature"); + + m_agentTestHelper->m_adapter->processData( + "2018-04-27T05:00:26.555666|ctmp|fault|X111|BAD|HIGH|Temperature is too high"); + ASSERT_TRUE(waitFor(5s, [&gotCondition]() { return gotCondition; })); +} diff --git a/test_package/mqtt_sink_2_test.cpp b/test_package/mqtt_sink_2_test.cpp deleted file mode 100644 index 93a8196d2..000000000 --- a/test_package/mqtt_sink_2_test.cpp +++ /dev/null @@ -1,434 +0,0 @@ -// -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Ensure that gtest is the first header otherwise Windows raises an error -#include -// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) - -#include - -#include - -#include "agent_test_helper.hpp" -#include "json_helper.hpp" -#include "mtconnect/buffer/checkpoint.hpp" -#include "mtconnect/device_model/data_item/data_item.hpp" -#include "mtconnect/entity/entity.hpp" -#include "mtconnect/entity/json_parser.hpp" -#include "mtconnect/mqtt/mqtt_client_impl.hpp" -#include "mtconnect/mqtt/mqtt_server_impl.hpp" -#include "mtconnect/printer//json_printer.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt2_service.hpp" -#include "test_utilities.hpp" - -using namespace std; -using namespace mtconnect; -using namespace mtconnect::device_model::data_item; -using namespace mtconnect::sink::mqtt_sink; -using namespace mtconnect::asset; -using namespace mtconnect::configuration; - -// main -int main(int argc, char *argv[]) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - -using json = nlohmann::json; - -class MqttSink2Test : public testing::Test -{ -protected: - void SetUp() override - { - m_agentTestHelper = make_unique(); - m_jsonPrinter = std::make_unique(2, true); - } - - void TearDown() override - { - const auto agent = m_agentTestHelper->getAgent(); - if (agent) - { - m_agentTestHelper->getAgent()->stop(); - m_agentTestHelper->m_ioContext.run_for(100ms); - } - if (m_client) - { - m_client->stop(); - m_agentTestHelper->m_ioContext.run_for(500ms); - m_client.reset(); - } - if (m_server) - { - m_server->stop(); - m_agentTestHelper->m_ioContext.run_for(500ms); - m_server.reset(); - } - m_agentTestHelper.reset(); - m_jsonPrinter.reset(); - } - - void createAgent(std::string testFile = {}, ConfigOptions options = {}) - { - if (testFile == "") - testFile = "/samples/test_config.xml"; - - ConfigOptions opts(options); - MergeOptions(opts, {{"Mqtt2Sink", true}, - {configuration::MqttPort, m_port}, - {MqttCurrentInterval, 200ms}, - {MqttSampleInterval, 100ms}, - {configuration::MqttHost, "127.0.0.1"s}}); - m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.0", 25, false, true, opts); - addAdapter(); - - m_agentTestHelper->getAgent()->start(); - } - - void createServer(const ConfigOptions &options) - { - using namespace mtconnect::configuration; - ConfigOptions opts(options); - MergeOptions(opts, {{ServerIp, "127.0.0.1"s}, - {MqttPort, 0}, - {MqttTls, false}, - {AutoAvailable, false}, - {RealTime, false}}); - - m_server = - make_shared(m_agentTestHelper->m_ioContext, opts); - } - - template - bool waitFor(const chrono::duration &time, function pred) - { - boost::asio::steady_timer timer(m_agentTestHelper->m_ioContext); - timer.expires_after(time); - bool timeout = false; - timer.async_wait([&timeout](boost::system::error_code ec) { - if (!ec) - { - timeout = true; - } - }); - - while (!timeout && !pred()) - { - m_agentTestHelper->m_ioContext.run_for(100ms); - } - timer.cancel(); - - return pred(); - } - - void startServer() - { - if (m_server) - { - bool start = m_server->start(); - if (start) - { - m_port = m_server->getPort(); - m_agentTestHelper->m_ioContext.run_for(500ms); - } - } - } - - void createClient(const ConfigOptions &options, unique_ptr &&handler) - { - ConfigOptions opts(options); - MergeOptions(opts, {{MqttHost, "127.0.0.1"s}, - {MqttPort, m_port}, - {MqttTls, false}, - {AutoAvailable, false}, - {RealTime, false}}); - m_client = make_shared(m_agentTestHelper->m_ioContext, - opts, std::move(handler)); - } - - bool startClient() - { - bool started = m_client && m_client->start(); - if (started) - { - return waitFor(1s, [this]() { return m_client->isConnected(); }); - } - return started; - } - - void addAdapter(ConfigOptions options = ConfigOptions {}) - { - m_agentTestHelper->addAdapter(options, "localhost", 0, - m_agentTestHelper->m_agent->getDefaultDevice()->getName()); - } - - std::unique_ptr m_jsonPrinter; - std::shared_ptr m_server; - std::shared_ptr m_client; - std::unique_ptr m_agentTestHelper; - uint16_t m_port {0}; -}; - -TEST_F(MqttSink2Test, mqtt_sink_flat_formatt_check) -{ - ConfigOptions options {{MqttMaxTopicDepth, 9}, {ProbeTopic, "Device/F/l/a/t/F/o/r/m/a/t"s}}; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent("", options); - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(10s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotDevice = false; - handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Probe/000", topic); - - ErrorList list; - auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); - EXPECT_EQ(0, list.size()); - auto dev = dynamic_pointer_cast(ptr); - EXPECT_TRUE(dev); - EXPECT_EQ("LinuxCNC", dev->getComponentName()); - EXPECT_EQ("000", *dev->getUuid()); - - gotDevice = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Probe/000"); - - createAgent(); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - - ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Sample) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotSample = false; - bool first = true; - handler->m_receive = [&gotSample, &first](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - if (first) - { - first = false; - } - else - { - EXPECT_EQ("MTConnect/Sample/000", topic); - - auto jdoc = json::parse(payload); - auto streams = jdoc.at("/MTConnectStreams/Streams/0/DeviceStream"_json_pointer); - EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); - - gotSample = true; - } - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Sample/000"); - - createAgent(); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&first]() { return !first; })); - ASSERT_FALSE(first); - - m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); - ASSERT_TRUE(waitFor(10s, [&gotSample]() { return gotSample; })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Current) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotCurrent = false; - handler->m_receive = [&gotCurrent](std::shared_ptr client, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Current/000", topic); - - auto jdoc = json::parse(payload); - auto streams = jdoc.at("/MTConnectStreams/Streams/0/DeviceStream"_json_pointer); - EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); - - gotCurrent = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Current/000"); - - createAgent(); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - ASSERT_TRUE(gotCurrent); - - gotCurrent = false; - ASSERT_TRUE(waitFor(1s, [&gotCurrent]() { return gotCurrent; })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_with_uuid_first) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotDevice = false; - handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/000/Probe", topic); - - ErrorList list; - auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); - EXPECT_EQ(0, list.size()); - auto dev = dynamic_pointer_cast(ptr); - EXPECT_TRUE(dev); - EXPECT_EQ("LinuxCNC", dev->getComponentName()); - EXPECT_EQ("000", *dev->getUuid()); - - gotDevice = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/000/Probe"); - - createAgent("", {{configuration::ProbeTopic, "MTConnect/[device]/Probe"s}}); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - - ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_no_device_in_format) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotDevice = false; - handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Probe/000", topic); - - ErrorList list; - auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); - EXPECT_EQ(0, list.size()); - auto dev = dynamic_pointer_cast(ptr); - EXPECT_TRUE(dev); - EXPECT_EQ("LinuxCNC", dev->getComponentName()); - EXPECT_EQ("000", *dev->getUuid()); - - gotDevice = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Probe/000"); - - createAgent("", {{configuration::ProbeTopic, "MTConnect/Probe"s}}); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - - ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); -} - -TEST_F(MqttSink2Test, mqtt_sink_should_publish_agent_device) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - DevicePtr ad; - string agent_topic; - - auto handler = make_unique(); - bool gotDevice = false; - handler->m_receive = [&gotDevice, &parser, &agent_topic, &ad](std::shared_ptr client, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ(agent_topic, topic); - gotDevice = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent(); - - ad = m_agentTestHelper->m_agent->getAgentDevice(); - agent_topic = "MTConnect/Probe/Agent_"s + *ad->getUuid(); - m_client->subscribe(agent_topic); - - auto service = m_agentTestHelper->getMqtt2Service(); - - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - - ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); -} diff --git a/test_package/mqtt_sink_test.cpp b/test_package/mqtt_sink_test.cpp index f8a46e246..1d5eb23ce 100644 --- a/test_package/mqtt_sink_test.cpp +++ b/test_package/mqtt_sink_test.cpp @@ -14,10 +14,6 @@ // See the License for the specific language governing permissions and // limitations under the License. // - -/// @file -/// Test MQTT 1 Service - // Ensure that gtest is the first header otherwise Windows raises an error #include // Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) @@ -27,6 +23,7 @@ #include #include "agent_test_helper.hpp" +#include "json_helper.hpp" #include "mtconnect/buffer/checkpoint.hpp" #include "mtconnect/device_model/data_item/data_item.hpp" #include "mtconnect/entity/entity.hpp" @@ -35,6 +32,7 @@ #include "mtconnect/mqtt/mqtt_server_impl.hpp" #include "mtconnect/printer//json_printer.hpp" #include "mtconnect/sink/mqtt_sink/mqtt_service.hpp" +#include "test_utilities.hpp" using namespace std; using namespace mtconnect; @@ -52,7 +50,7 @@ int main(int argc, char *argv[]) using json = nlohmann::json; -class MqttSinkTest : public testing::Test +class MqttSink2Test : public testing::Test { protected: void SetUp() override @@ -72,7 +70,7 @@ class MqttSinkTest : public testing::Test if (m_client) { m_client->stop(); - m_agentTestHelper->m_ioContext.run_for(100ms); + m_agentTestHelper->m_ioContext.run_for(500ms); m_client.reset(); } if (m_server) @@ -95,8 +93,10 @@ class MqttSinkTest : public testing::Test ConfigOptions opts(options); MergeOptions(opts, {{"MqttSink", true}, {configuration::MqttPort, m_port}, + {MqttCurrentInterval, 200ms}, + {MqttSampleInterval, 100ms}, {configuration::MqttHost, "127.0.0.1"s}}); - m_agentTestHelper->createAgent(testFile, 8, 4, "2.0", 25, false, true, opts); + m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.0", 25, false, true, opts); addAdapter(); m_agentTestHelper->getAgent()->start(); @@ -120,7 +120,7 @@ class MqttSinkTest : public testing::Test bool waitFor(const chrono::duration &time, function pred) { boost::asio::steady_timer timer(m_agentTestHelper->m_ioContext); - timer.expires_from_now(time); + timer.expires_after(time); bool timeout = false; timer.async_wait([&timeout](boost::system::error_code ec) { if (!ec) @@ -168,7 +168,7 @@ class MqttSinkTest : public testing::Test bool started = m_client && m_client->start(); if (started) { - return waitFor(5s, [this]() { return m_client->isConnected(); }); + return waitFor(1s, [this]() { return m_client->isConnected(); }); } return started; } @@ -182,36 +182,13 @@ class MqttSinkTest : public testing::Test std::unique_ptr m_jsonPrinter; std::shared_ptr m_server; std::shared_ptr m_client; - std::shared_ptr m_service; std::unique_ptr m_agentTestHelper; uint16_t m_port {0}; }; -TEST_F(MqttSinkTest, mqtt_sink_should_be_loaded_by_agent) -{ - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - - ASSERT_TRUE(service); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker) +TEST_F(MqttSink2Test, mqtt_sink_flat_formatt_check) { - ConfigOptions options; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_with_UserNameandPassword) -{ - ConfigOptions options {{MqttUserName, "MQTT-SINK"s}, {MqttPassword, "mtconnect"s}}; + ConfigOptions options {{MqttMaxTopicDepth, 9}, {ProbeTopic, "Device/F/l/a/t/F/o/r/m/a/t"s}}; createServer(options); startServer(); @@ -220,24 +197,10 @@ TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_with_UserNameandPassword createAgent("", options); auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_without_UserNameandPassword) -{ - ConfigOptions options; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + ASSERT_TRUE(waitFor(10s, [&service]() { return service->isConnected(); })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_device) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe) { ConfigOptions options; createServer(options); @@ -250,7 +213,7 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_device) bool gotDevice = false; handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Device/000", topic); + EXPECT_EQ("MTConnect/Probe/000", topic); ErrorList list; auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); @@ -265,18 +228,18 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_device) createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Device/000"); + m_client->subscribe("MTConnect/Probe/000"); createAgent(); auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - ASSERT_TRUE(waitFor(5s, [&gotDevice]() { return gotDevice; })); + ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Streams) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_Sample) { ConfigOptions options; createServer(options); @@ -286,63 +249,34 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Streams) entity::JsonParser parser; auto handler = make_unique(); - bool foundLineDataItem = false; - handler->m_receive = [&foundLineDataItem](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]", topic); + bool gotSample = false; + handler->m_receive = [&gotSample](std::shared_ptr client, const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Sample/000", topic); auto jdoc = json::parse(payload); - string value = jdoc.at("/value"_json_pointer).get(); - foundLineDataItem = value == "204"; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); + auto streams = jdoc.at("/MTConnectStreams/Streams/0/DeviceStream"_json_pointer); + EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - - m_client->subscribe("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]"); - m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); - - ASSERT_TRUE(waitFor(5s, [&foundLineDataItem]() { return foundLineDataItem; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Asset) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Asset/0001", topic); - auto jdoc = json::parse(payload); - string id = jdoc.at("/Part/assetId"_json_pointer).get(); - EXPECT_EQ("0001", id); - gotControllerDataItem = true; + gotSample = true; }; + createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); + m_client->subscribe("MTConnect/Sample/000"); createAgent(); + auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Asset/0001"); - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|@ASSET@|@1|Part|TEST 1"); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); + ASSERT_FALSE(gotSample); - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); + m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); + ASSERT_TRUE(waitFor(10s, [&gotSample]() { return gotSample; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_RotaryMode) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_Current) { ConfigOptions options; createServer(options); @@ -352,135 +286,34 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_RotaryMode) entity::JsonParser parser; auto handler = make_unique(); - bool gotRotaryMode = false; - handler->m_receive = [&gotRotaryMode](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]", - topic); + bool gotCurrent = false; + handler->m_receive = [&gotCurrent](std::shared_ptr client, const std::string &topic, + const std::string &payload) { + EXPECT_EQ("MTConnect/Current/000", topic); + auto jdoc = json::parse(payload); + auto streams = jdoc.at("/MTConnectStreams/Streams/0/DeviceStream"_json_pointer); + EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); - double v = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(5000.0, v); - gotRotaryMode = true; + gotCurrent = true; }; createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); + m_client->subscribe("MTConnect/Current/000"); createAgent(); - auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]"); - - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|block|G01X00|Sspeed|5000|line|204"); - - ASSERT_TRUE(waitFor(5s, [&gotRotaryMode]() { return gotRotaryMode; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Dataset) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]", - topic); - auto jdoc = json::parse(payload); - auto id = jdoc.at("/value/a"_json_pointer).get(); - EXPECT_EQ(1, id); - gotControllerDataItem = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent("/samples/data_set.xml"); - auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]"); - - m_agentTestHelper->m_adapter->processData("TIME|vars|a=1 b=2 c=3"); - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); -} -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Table) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/WorkOffsetTable[wpo]", - topic); - auto jdoc = json::parse(payload); - - auto jValue = jdoc.at("/value"_json_pointer); - int count = 0; - if (jValue.is_object()) - { - for (auto &[key, value] : jValue.items()) - { - if (key == "G53.1" || key == "G53.2" || key == "G53.3") - { - for (auto &[subKey, subValue] : value.items()) - { - if (key == "G53.1" && ((subKey == "X" && subValue.get() == 1) || - (subKey == "Y" && subValue.get() == 2) || - (subKey == "Z" && subValue.get() == 3))) - { - count++; - } - else if (key == "G53.2" && ((subKey == "X" && subValue.get() == 4) || - (subKey == "Y" && subValue.get() == 5) || - (subKey == "Z" && subValue.get() == 6))) - { - count++; - } - else if (key == "G53.3" && ((subKey == "X" && subValue.get() == 7.0) || - (subKey == "Y" && subValue.get() == 8.0) || - (subKey == "Z" && subValue.get() == 9.0) || - (subKey == "U" && subValue.get() == 10.0))) - { - count++; - } - } - } - } - EXPECT_EQ(10, count); - gotControllerDataItem = true; - } - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent("/samples/data_set.xml"); auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/" - "WorkOffsetTable[wpo]"); - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|wpo|G53.1={X=1.0 Y=2.0 Z=3.0} G53.2={X=4.0 Y=5.0 Z=6.0}" - "G53.3={X=7.0 Y=8.0 Z=9 U=10.0}"); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); + ASSERT_TRUE(gotCurrent); - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); + gotCurrent = false; + ASSERT_TRUE(waitFor(1s, [&gotCurrent]() { return gotCurrent; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Temperature) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_with_uuid_first) { ConfigOptions options; createServer(options); @@ -490,64 +323,36 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Temperature) entity::JsonParser parser; auto handler = make_unique(); - bool gotTemperature = false; - handler->m_receive = [&gotTemperature](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" - "Temperature[z_motor_temp]", - topic); - auto jdoc = json::parse(payload); + bool gotDevice = false; + handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, + const std::string &topic, const std::string &payload) { + EXPECT_EQ("MTConnect/000/Probe", topic); + + ErrorList list; + auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); + EXPECT_EQ(0, list.size()); + auto dev = dynamic_pointer_cast(ptr); + EXPECT_TRUE(dev); + EXPECT_EQ("LinuxCNC", dev->getComponentName()); + EXPECT_EQ("000", *dev->getUuid()); - auto value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(81.0, value); - gotTemperature = true; + gotDevice = true; }; createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); + m_client->subscribe("MTConnect/000/Probe"); - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" - "Temperature[z_motor_temp]"); - - m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|z_motor_temp|81"); - - ASSERT_TRUE(waitFor(5s, [&gotTemperature]() { return gotTemperature; })); -} + createAgent("", {{configuration::ProbeTopic, "MTConnect/[device]/Probe"s}}); -TEST_F(MqttSinkTest, mqtt_sink_should_publish_LinearLoad) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotLinearLoad = false; - handler->m_receive = [&gotLinearLoad](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]", topic); - auto jdoc = json::parse(payload); - auto value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(50.0, value); - gotLinearLoad = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent(); auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]"); - m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|Xload|50"); - ASSERT_TRUE(waitFor(5s, [&gotLinearLoad]() { return gotLinearLoad; })); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); + + ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSinkTest, mqtt_sink_should_publish_DynamicCalibration) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_no_device_in_format) { ConfigOptions options; createServer(options); @@ -557,75 +362,67 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_DynamicCalibration) entity::JsonParser parser; auto handler = make_unique(); - bool gotCalibration = false; - handler->m_receive = [this, &gotCalibration](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]", - topic); - auto jdoc = json::parse(payload); + bool gotDevice = false; + handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, + const std::string &topic, const std::string &payload) { + EXPECT_EQ("MTConnect/Probe/000", topic); - auto value = jdoc.at("/value"_json_pointer); - ASSERT_TRUE(value.is_array()); - EXPECT_EQ(25, value.size()); - gotCalibration = true; + ErrorList list; + auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); + EXPECT_EQ(0, list.size()); + auto dev = dynamic_pointer_cast(ptr); + EXPECT_TRUE(dev); + EXPECT_EQ("LinuxCNC", dev->getComponentName()); + EXPECT_EQ("000", *dev->getUuid()); + + gotDevice = true; }; createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); + m_client->subscribe("MTConnect/Probe/000"); - createAgent(); - auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); + createAgent("", {{configuration::ProbeTopic, "MTConnect/Probe"s}}); - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]"); + auto service = m_agentTestHelper->getMqttService(); - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|Xts|25|| 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 " - "5119 5119 5118 " - "5118 5117 5117 5119 5119 5118 5118 5118 5118 5118"); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - ASSERT_TRUE(waitFor(5s, [&gotCalibration]() { return gotCalibration; })); + ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -/// @test check if the condition includes the state as the key -TEST_F(MqttSinkTest, mqtt_should_publish_conditions_with_the_state_as_the_key) +TEST_F(MqttSink2Test, mqtt_sink_should_publish_agent_device) { ConfigOptions options; createServer(options); startServer(); ASSERT_NE(0, m_port); + entity::JsonParser parser; - auto handler = make_unique(); - bool gotCondition = false; - handler->m_receive = [&gotCondition](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature", topic); - auto jdoc = json::parse(payload); - EXPECT_EQ("Temperature is too high", jdoc.at("/Fault/value"_json_pointer).get()); - EXPECT_EQ("X111", jdoc.at("/Fault/nativeCode"_json_pointer).get()); - EXPECT_EQ("BAD", jdoc.at("/Fault/nativeSeverity"_json_pointer).get()); - EXPECT_EQ("HIGH", jdoc.at("/Fault/qualifier"_json_pointer).get()); - EXPECT_EQ("TEMPERATURE", jdoc.at("/Fault/type"_json_pointer).get()); + DevicePtr ad; + string agent_topic; - gotCondition = true; + auto handler = make_unique(); + bool gotDevice = false; + handler->m_receive = [&gotDevice, &parser, &agent_topic, &ad](std::shared_ptr client, + const std::string &topic, + const std::string &payload) { + EXPECT_EQ(agent_topic, topic); + gotDevice = true; }; + createClient(options, std::move(handler)); ASSERT_TRUE(startClient()); createAgent(); - auto di = m_agentTestHelper->m_agent->getDataItemById("ctmp"); - ASSERT_TRUE(di); - ASSERT_EQ("000/Axes[Axes]/Rotary[C]/Condition/Temperature", di->getTopic()); + ad = m_agentTestHelper->m_agent->getAgentDevice(); + agent_topic = "MTConnect/Probe/Agent_"s + *ad->getUuid(); + m_client->subscribe(agent_topic); auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature"); - m_agentTestHelper->m_adapter->processData( - "2018-04-27T05:00:26.555666|ctmp|fault|X111|BAD|HIGH|Temperature is too high"); - ASSERT_TRUE(waitFor(5s, [&gotCondition]() { return gotCondition; })); + ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); + + ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } From 9274527224cf7401c2cb8847182382869246f44a Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 22:14:49 -0400 Subject: [PATCH 091/128] fixed cancel --- src/mtconnect/observation/change_observer.cpp | 3 ++- src/mtconnect/observation/change_observer.hpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 25 ++++++++++++++----- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index e186a592b..a2c8a1516 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -47,7 +47,8 @@ namespace mtconnect::observation { void ChangeObserver::handler(boost::system::error_code ec) { - boost::asio::post(m_strand, boost::bind(m_handler, ec)); + if (m_handler) + boost::asio::post(m_strand, boost::bind(m_handler, ec)); } // Signaler Management diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index b38cc6161..4591e0828 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -147,9 +147,9 @@ namespace mtconnect::observation { void clear() { std::unique_lock lock(m_mutex); + m_timer.cancel(); m_signalers.clear(); m_handler.clear(); - m_timer.cancel(); } private: diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 2361894b4..0353686ab 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -116,7 +116,7 @@ namespace mtconnect { {"format", QUERY, "The format of the response document: 'xml' or 'json'"}, {"heartbeat", QUERY, "Time in ms between publishing a empty document when no data has changed"}, - {"requestId", PATH, "webservice request id"}}); + {"id", PATH, "webservice request id"}}); createProbeRoutings(); createCurrentRoutings(); @@ -765,8 +765,21 @@ namespace mtconnect { }; auto cancelHandler = [&](SessionPtr session, RequestPtr request) -> bool { - auto requestId = *request->parameter("requestId"); - return session->cancelRequest(requestId); + if (request->m_requestId) + { + auto requestId = *request->m_requestId; + auto success = session->cancelRequest(requestId); + auto response = make_unique( + status::ok, "{ \"success\": \""s + (success ? "true" : "false") + "\"}", + "application/json"); + + respond(session, std::move(response), request->m_requestId); + return true; + } + else + { + return false; + } }; string qp( @@ -786,9 +799,9 @@ namespace mtconnect { "optionally filtered by the `path` and starting at `from`. By default, from is " "the first available observation known to the agent") .command("sample"); - m_server - ->addRouting({boost::beast::http::verb::get, "/cancel/requestId={string}", cancelHandler}) - .document("MTConnect WebServices Cancel Stream", "Cancels a streaming sample request"); + m_server->addRouting({boost::beast::http::verb::get, "/cancel/id={string}", cancelHandler}) + .document("MTConnect WebServices Cancel Stream", "Cancels a streaming sample request") + .command("cancel"); } void RestService::createPutObservationRoutings() From ed4fe9e73d4ea4e260e448526438c87d05b66faa Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 24 Apr 2024 22:59:06 -0400 Subject: [PATCH 092/128] refactored async observer and created abstract async response to cancel timed responses --- src/mtconnect/observation/change_observer.cpp | 2 +- src/mtconnect/observation/change_observer.hpp | 46 ++++++++++++------- src/mtconnect/sink/rest_sink/rest_service.cpp | 33 ++++++++----- src/mtconnect/sink/rest_sink/session.hpp | 4 +- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index a2c8a1516..b15a646e9 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -100,7 +100,7 @@ namespace mtconnect::observation { buffer::CircularBuffer &buffer, FilterSet &&filter, std::chrono::milliseconds interval, std::chrono::milliseconds heartbeat) - : m_interval(interval), + : AsyncResponse(interval), m_heartbeat(heartbeat), m_last(std::chrono::system_clock::now()), m_filter(std::move(filter)), diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index 4591e0828..e3f5bc40b 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -194,6 +194,32 @@ namespace mtconnect::observation { std::list m_observers; }; + /// @brief Abstract class for things asynchronouos timers + class AGENT_LIB_API AsyncResponse : public std::enable_shared_from_this + { + public: + AsyncResponse(std::chrono::milliseconds interval) : m_interval(interval) {} + + virtual bool cancel() = 0; + + /// @brief method to determine if the sink is running + virtual bool isRunning() = 0; + + /// @brief get the request id for webservices + const auto &getRequestId() const { return m_requestId; } + + /// @brief sets the optonal request id for webservices. + void setRequestId(const std::optional &id) { m_requestId = id; } + + /// @brief Get the interval + const auto &getInterval() const { return m_interval; } + + protected: + std::chrono::milliseconds m_interval { + 0}; //! the minimum amout of time to wait before calling the handler + std::optional m_requestId; //! request id + }; + /// @brief Asyncronous change context for waiting for changes /// /// This class must be subclassed and provide a fail and isRunning method. @@ -205,7 +231,7 @@ namespace mtconnect::observation { /// /// The handler and sequence numbers are handled inside the circular buffer lock to prevent race /// conditions with incoming data. - class AGENT_LIB_API AsyncObserver : public std::enable_shared_from_this + class AGENT_LIB_API AsyncObserver : public AsyncResponse { public: /// @Brief callback when observations are ready @@ -226,7 +252,7 @@ namespace mtconnect::observation { virtual ~AsyncObserver() = default; /// @brief Get a shared pointed - auto getptr() const { return const_cast(this)->shared_from_this(); } + auto getptr() { return std::dynamic_pointer_cast(shared_from_this()); } /// @brief sets up the `ChangeObserver` using the filter and initializes the references to the /// buffer @@ -244,11 +270,8 @@ namespace mtconnect::observation { /// @brief abstract call to failure handler virtual void fail(boost::beast::http::status status, const std::string &message) = 0; - /// @brief method to determine if the sink is running - virtual bool isRunning() = 0; - /// @brief Stop all timers and release resources. - virtual bool cancel() + bool cancel() override { m_observer.clear(); return true; @@ -266,14 +289,6 @@ namespace mtconnect::observation { auto getSequence() const { return m_sequence; } auto isEndOfBuffer() const { return m_endOfBuffer; } const auto &getFilter() const { return m_filter; } - const auto &getRequestId() const { return m_requestId; } - ///@} - - ///@{ - /// @name setters - - /// @brief sets the optonal request id for webservices. - void setRequestId(const std::optional &id) { m_requestId = id; } ///@} mutable bool m_endOfBuffer {false}; //! Public indicator that we are at the end of the buffer @@ -288,8 +303,6 @@ namespace mtconnect::observation { protected: SequenceNumber_t m_sequence {0}; //! the current sequence number - std::chrono::milliseconds m_interval { - 0}; //! the minimum amout of time to wait before calling the handler std::chrono::milliseconds m_heartbeat { 0}; //! the maximum amount of time to wait before sending a heartbeat std::chrono::system_clock::time_point m_last; //! the last time the handler completed @@ -298,6 +311,5 @@ namespace mtconnect::observation { ChangeObserver m_observer; //! the change observer mtconnect::buffer::CircularBuffer &m_buffer; //! reference to the circular buffer - std::optional m_requestId; //! request id }; } // namespace mtconnect::observation diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 0353686ab..129590561 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -1122,20 +1122,30 @@ namespace mtconnect { return 0; } - struct AsyncCurrentResponse + struct AsyncCurrentResponse : public AsyncResponse { - AsyncCurrentResponse(rest_sink::SessionPtr session, asio::io_context &context) - : m_session(session), m_timer(context) + AsyncCurrentResponse(rest_sink::SessionPtr session, asio::io_context &context, + chrono::milliseconds interval) + : AsyncResponse(interval), m_session(session), m_timer(context) {} + auto getptr() { return dynamic_pointer_cast(shared_from_this()); } + + bool cancel() override + { + m_timer.cancel(); + m_session.reset(); + return true; + } + + bool isRunning() override { return (bool)m_session; } + std::weak_ptr m_service; rest_sink::SessionPtr m_session; - chrono::milliseconds m_interval; const Printer *m_printer {nullptr}; FilterSetOpt m_filter; boost::asio::steady_timer m_timer; bool m_pretty {false}; - std::optional m_requestId; }; void RestService::streamCurrentRequest(SessionPtr session, const Printer *printer, @@ -1152,17 +1162,18 @@ namespace mtconnect { dev = checkDevice(printer, *device); } - auto asyncResponse = make_shared(session, m_context); + auto asyncResponse = + make_shared(session, m_context, chrono::milliseconds {interval}); if (path || device || deviceType) { asyncResponse->m_filter = make_optional(); checkPath(printer, path, dev, *asyncResponse->m_filter, deviceType); } - asyncResponse->m_interval = chrono::milliseconds {interval}; asyncResponse->m_printer = printer; asyncResponse->m_service = getptr(); asyncResponse->m_pretty = pretty; - asyncResponse->m_requestId = requestId; + asyncResponse->setRequestId(requestId); + session->addObserver(asyncResponse); asyncResponse->m_session->beginStreaming( printer->mimeType(), @@ -1205,16 +1216,16 @@ namespace mtconnect { asyncResponse->m_session->writeChunk( fetchCurrentData(asyncResponse->m_printer, asyncResponse->m_filter, nullopt, - asyncResponse->m_pretty, asyncResponse->m_requestId), + asyncResponse->m_pretty, asyncResponse->getRequestId()), boost::asio::bind_executor( m_strand, [this, asyncResponse]() { - asyncResponse->m_timer.expires_from_now(asyncResponse->m_interval); + asyncResponse->m_timer.expires_from_now(asyncResponse->getInterval()); asyncResponse->m_timer.async_wait(boost::asio::bind_executor( m_strand, boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); }), - asyncResponse->m_requestId); + asyncResponse->getRequestId()); } catch (RequestError &re) { diff --git a/src/mtconnect/sink/rest_sink/session.hpp b/src/mtconnect/sink/rest_sink/session.hpp index ba690894f..c49a26586 100644 --- a/src/mtconnect/sink/rest_sink/session.hpp +++ b/src/mtconnect/sink/rest_sink/session.hpp @@ -120,7 +120,7 @@ namespace mtconnect::sink::rest_sink { } /// @brief Add an observer to the list for cleanup later. - void addObserver(std::weak_ptr observer) + void addObserver(std::weak_ptr observer) { m_observers.push_back(observer); } @@ -148,7 +148,7 @@ namespace mtconnect::sink::rest_sink { bool m_allowPuts {false}; std::set m_allowPutsFrom; boost::asio::ip::tcp::endpoint m_remote; - std::list> m_observers; + std::list> m_observers; }; } // namespace mtconnect::sink::rest_sink From 3710a92c6ea74cba38fa9a81754586617801c2e3 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 25 Apr 2024 12:57:02 -0400 Subject: [PATCH 093/128] Fixed race in change observer destructor. --- src/mtconnect/observation/change_observer.cpp | 11 +++ src/mtconnect/observation/change_observer.hpp | 8 +-- src/mtconnect/sink/rest_sink/rest_service.cpp | 71 +++++++++++-------- 3 files changed, 55 insertions(+), 35 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index b15a646e9..e106bb62e 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -29,14 +29,25 @@ using namespace std; namespace mtconnect::observation { ChangeObserver::~ChangeObserver() { + std::lock_guard scopedLock(m_mutex); + clear(); + } + + void ChangeObserver::clear() + { + std::unique_lock lock(m_mutex); + m_timer.cancel(); + m_handler.clear(); for (const auto signaler : m_signalers) signaler->removeObserver(this); + m_signalers.clear(); } void ChangeObserver::addSignaler(ChangeSignaler *sig) { m_signalers.emplace_back(sig); } bool ChangeObserver::removeSignaler(ChangeSignaler *sig) { + std::lock_guard scopedLock(m_mutex); auto newEndPos = std::remove(m_signalers.begin(), m_signalers.end(), sig); if (newEndPos == m_signalers.end()) return false; diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index e3f5bc40b..c274e848e 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -144,13 +144,7 @@ namespace mtconnect::observation { ///@} /// @brief clear the observer information. - void clear() - { - std::unique_lock lock(m_mutex); - m_timer.cancel(); - m_signalers.clear(); - m_handler.clear(); - } + void clear(); private: boost::asio::io_context::strand &m_strand; diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 129590561..37e326cdc 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -1093,12 +1093,14 @@ namespace mtconnect { if (m_logStreamData) asyncResponse->m_log << content << endl; - asyncResponse->m_session->writeChunk( - content, - asio::bind_executor(m_strand, - boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), - asyncResponse->getRequestId()); - + if (asyncResponse->m_session) + { + asyncResponse->m_session->writeChunk( + content, + asio::bind_executor(m_strand, + boost::bind(&AsyncObserver::handlerCompleted, asyncResponse)), + asyncResponse->getRequestId()); + } return end; } @@ -1106,9 +1108,12 @@ namespace mtconnect { { LOG(error) << asyncResponse->m_session->getRemote().address() << ": Error processing request: " << re.what(); - ResponsePtr resp = std::make_unique(re); - asyncResponse->m_session->writeResponse(std::move(resp)); - asyncResponse->m_session->close(); + if (asyncResponse->m_session) + { + ResponsePtr resp = std::make_unique(re); + asyncResponse->m_session->writeResponse(std::move(resp)); + asyncResponse->m_session->close(); + } } catch (...) @@ -1197,7 +1202,7 @@ namespace mtconnect { if (!service || !m_server || !m_server->isRunning()) { LOG(warning) << "Trying to send chunk when service has stopped"; - if (service) + if (service && asyncResponse->m_session) { asyncResponse->m_session->fail(boost::beast::http::status::internal_server_error, "Agent shutting down, aborting stream"); @@ -1209,31 +1214,38 @@ namespace mtconnect { { LOG(warning) << "Unexpected error streamNextCurrent, aborting"; LOG(warning) << ec.category().message(ec.value()) << ": " << ec.message(); - asyncResponse->m_session->fail(boost::beast::http::status::internal_server_error, - "Unexpected error streamNextCurrent, aborting"); + if (asyncResponse->m_session) + asyncResponse->m_session->fail(boost::beast::http::status::internal_server_error, + "Unexpected error streamNextCurrent, aborting"); return; } - asyncResponse->m_session->writeChunk( - fetchCurrentData(asyncResponse->m_printer, asyncResponse->m_filter, nullopt, - asyncResponse->m_pretty, asyncResponse->getRequestId()), - boost::asio::bind_executor( - m_strand, - [this, asyncResponse]() { - asyncResponse->m_timer.expires_from_now(asyncResponse->getInterval()); - asyncResponse->m_timer.async_wait(boost::asio::bind_executor( - m_strand, - boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); - }), - asyncResponse->getRequestId()); + if (asyncResponse->m_session) + { + asyncResponse->m_session->writeChunk( + fetchCurrentData(asyncResponse->m_printer, asyncResponse->m_filter, nullopt, + asyncResponse->m_pretty, asyncResponse->getRequestId()), + boost::asio::bind_executor( + m_strand, + [this, asyncResponse]() { + asyncResponse->m_timer.expires_from_now(asyncResponse->getInterval()); + asyncResponse->m_timer.async_wait(boost::asio::bind_executor( + m_strand, + boost::bind(&RestService::streamNextCurrent, this, asyncResponse, _1))); + }), + asyncResponse->getRequestId()); + } } catch (RequestError &re) { LOG(error) << asyncResponse->m_session->getRemote().address() << ": Error processing request: " << re.what(); - ResponsePtr resp = std::make_unique(re); - asyncResponse->m_session->writeResponse(std::move(resp)); - asyncResponse->m_session->close(); + if (asyncResponse->m_session) + { + ResponsePtr resp = std::make_unique(re); + asyncResponse->m_session->writeResponse(std::move(resp)); + asyncResponse->m_session->close(); + } } catch (...) @@ -1241,7 +1253,10 @@ namespace mtconnect { std::stringstream txt; txt << asyncResponse->m_session->getRemote().address() << ": Unknown Error thrown"; LOG(error) << txt.str(); - asyncResponse->m_session->fail(boost::beast::http::status::not_found, txt.str()); + if (asyncResponse->m_session) + { + asyncResponse->m_session->fail(boost::beast::http::status::not_found, txt.str()); + } } } From 31ce248ed07cc04967c15f360fb9825db54f5cf8 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 27 Apr 2024 14:02:39 -0400 Subject: [PATCH 094/128] fixed requests in websockets --- src/mtconnect/observation/change_observer.cpp | 2 +- src/mtconnect/sink/rest_sink/request.hpp | 3 + .../sink/rest_sink/websocket_session.hpp | 57 ++++++++++--------- 3 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/mtconnect/observation/change_observer.cpp b/src/mtconnect/observation/change_observer.cpp index e106bb62e..f489b287c 100644 --- a/src/mtconnect/observation/change_observer.cpp +++ b/src/mtconnect/observation/change_observer.cpp @@ -32,7 +32,7 @@ namespace mtconnect::observation { std::lock_guard scopedLock(m_mutex); clear(); } - + void ChangeObserver::clear() { std::unique_lock lock(m_mutex); diff --git a/src/mtconnect/sink/rest_sink/request.hpp b/src/mtconnect/sink/rest_sink/request.hpp index ac3f2c33b..40eb12172 100644 --- a/src/mtconnect/sink/rest_sink/request.hpp +++ b/src/mtconnect/sink/rest_sink/request.hpp @@ -57,6 +57,9 @@ namespace mtconnect::sink::rest_sink { /// The request can be a simple reply response or streaming request struct Request { + Request() = default; + Request(const Request &request) = default; + boost::beast::http::verb m_verb; ///< GET, PUT, POST, or DELETE std::string m_body; ///< The body of the request std::string m_accepts; ///< The accepts header diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index f06b916c8..013d86016 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -42,6 +42,7 @@ namespace mtconnect::sink::rest_sink { std::optional m_streamBuffer; Complete m_complete; bool m_streaming {false}; + RequestPtr m_request; }; /// @brief A websocket session that provides a pubsub interface using REST parameters @@ -342,7 +343,10 @@ namespace mtconnect::sink::rest_sink { { // Extract the parameters from the json doc to map them to the REST // protocol parameters - m_request->m_verb = beast::http::verb::get; + auto request = make_unique(*m_request); + + request->m_verb = beast::http::verb::get; + request->m_parameters.clear(); const auto &object = doc.GetObject(); for (auto &it : object) @@ -353,58 +357,56 @@ namespace mtconnect::sink::rest_sink { // Skip nulls break; case rapidjson::kFalseType: - m_request->m_parameters.emplace(make_pair(it.name.GetString(), false)); + request->m_parameters.emplace(make_pair(it.name.GetString(), false)); break; case rapidjson::kTrueType: - m_request->m_parameters.emplace(make_pair(it.name.GetString(), true)); + request->m_parameters.emplace(make_pair(it.name.GetString(), true)); break; case rapidjson::kObjectType: break; case rapidjson::kArrayType: break; case rapidjson::kStringType: - m_request->m_parameters.emplace( + request->m_parameters.emplace( make_pair(it.name.GetString(), string(it.value.GetString()))); break; case rapidjson::kNumberType: if (it.value.Is()) - m_request->m_parameters.emplace( - make_pair(it.name.GetString(), it.value.Get())); + request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace( + request->m_parameters.emplace( make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace( + request->m_parameters.emplace( make_pair(it.name.GetString(), (uint64_t)it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace( + request->m_parameters.emplace( make_pair(it.name.GetString(), it.value.Get())); else if (it.value.Is()) - m_request->m_parameters.emplace( + request->m_parameters.emplace( make_pair(it.name.GetString(), it.value.Get())); break; } } - if (m_request->m_parameters.count("request") > 0) + if (request->m_parameters.count("request") > 0) { - m_request->m_command = get(m_request->m_parameters["request"]); - m_request->m_parameters.erase("request"); + request->m_command = get(request->m_parameters["request"]); + request->m_parameters.erase("request"); } - if (m_request->m_parameters.count("id") > 0) + if (request->m_parameters.count("id") > 0) { - auto &v = m_request->m_parameters["id"]; + auto &v = request->m_parameters["id"]; string id = visit(overloaded {[](monostate m) { return ""s; }, [](auto v) { return boost::lexical_cast(v); }}, v); - m_request->m_requestId = id; - m_request->m_parameters.erase("id"); + request->m_requestId = id; + request->m_parameters.erase("id"); } - auto &id = *(m_request->m_requestId); - + auto &id = *(request->m_requestId); auto res = m_requests.emplace(id, id); if (!res.second) { @@ -412,14 +414,17 @@ namespace mtconnect::sink::rest_sink { boost::system::error_code ec; fail(status::bad_request, "Duplicate request Id", ec); } - - if (!m_dispatch(derived().shared_ptr(), m_request)) + else { - ostringstream txt; - txt << "Failed to find handler for " << buffer; - LOG(error) << txt.str(); - boost::system::error_code ec; - fail(status::bad_request, "Duplicate request Id", ec); + res.first->second.m_request = std::move(request); + if (!m_dispatch(derived().shared_ptr(), res.first->second.m_request)) + { + ostringstream txt; + txt << "Failed to find handler for " << buffer; + LOG(error) << txt.str(); + boost::system::error_code ec; + fail(status::bad_request, "Duplicate request Id", ec); + } } } From 07d1ef0fef1a34695f92dbd4dba4be62b9b41473 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sat, 6 Apr 2024 17:25:04 -0400 Subject: [PATCH 095/128] Version 2.3.0.6 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 81d1e1c71..f5560bb92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) set(AGENT_VERSION_BUILD 0) -set(AGENT_VERSION_RC "RC1") +set(AGENT_VERSION_RC "RC2") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) From da0f664b9ffe2f8144843cb3346e492fe881b72d Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 11 Apr 2024 18:32:59 -0400 Subject: [PATCH 096/128] Fixed port in url for MQTT service. --- src/mtconnect/mqtt/mqtt_client_impl.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index f1d7273c6..3541cae9e 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -164,7 +164,6 @@ namespace mtconnect { m_connected = false; if (m_handler && m_handler->m_disconnected) m_handler->m_disconnected(shared_from_this()); - m_handler->m_disconnected(shared_from_this()); if (m_running) { disconnected(); From 2d7a5b20ed3658c6cb2798657ebfbdeae5d408f2 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 12 Apr 2024 09:52:41 -0400 Subject: [PATCH 097/128] fixed crash when closing mqtt client. set close handler to nullptr if already disconnected. --- src/mtconnect/mqtt/mqtt_client_impl.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index 3541cae9e..af71cf54c 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -475,7 +475,7 @@ namespace mtconnect { { return static_pointer_cast(shared_from_this()); } - + /// @brief Get the Mqtt TCP Client /// @return pointer to the Mqtt TCP Client auto &getClient() @@ -557,7 +557,7 @@ namespace mtconnect { { return static_pointer_cast(shared_from_this()); } - + /// @brief Get the Mqtt TLS WebSocket Client /// @return pointer to the Mqtt TLS WebSocket Client auto &getClient() @@ -596,7 +596,7 @@ namespace mtconnect { { return static_pointer_cast(shared_from_this()); } - + /// @brief Get the Mqtt TLS WebSocket Client /// @return pointer to the Mqtt TLS WebSocket Client auto &getClient() From d738b6d1ecad5f927e0b370e36c10492b8094cc0 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sun, 28 Apr 2024 12:58:57 -0400 Subject: [PATCH 098/128] Added initial value handling --- src/mtconnect/agent.cpp | 26 +++++++++---------- .../device_model/data_item/data_item.cpp | 5 ++++ .../device_model/data_item/data_item.hpp | 4 +-- test_package/agent_test.cpp | 23 ++++++++++++++++ 4 files changed, 43 insertions(+), 15 deletions(-) diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index 9340c3d18..af20d70e2 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -301,7 +301,7 @@ namespace mtconnect { { if (item.expired()) continue; - + auto di = item.lock(); if (di->hasInitialValue()) { @@ -309,7 +309,7 @@ namespace mtconnect { } } } - + std::lock_guard lock(m_circularBuffer); if (m_circularBuffer.addToBuffer(observation) != 0) { @@ -476,11 +476,11 @@ namespace mtconnect { changed = receiveDevice(device, true) || changed; if (changed) { - if (source) + if (source) + { + auto s = findSource(*source); + if (s) { - auto s = findSource(*source); - if (s) - { s->setOptions({{config::Device, uuid}}); } } @@ -578,7 +578,7 @@ namespace mtconnect { LOG(error) << "Device does not have a name: " << *device->getUuid(); return false; } - + verifyDevice(device); createUniqueIds(device); @@ -1016,7 +1016,7 @@ namespace mtconnect { if (m_agentDevice) { auto d = m_agentDevice->getDeviceDataItem("device_removed"); - if (d) + if (d) m_loopback->receive(d, oldUuid); } } @@ -1463,12 +1463,12 @@ namespace mtconnect { { try { - double fact_value = stod(factor); - double off_value = stod(offset); + double fact_value = stod(factor); + double off_value = stod(offset); - device_model::data_item::UnitConversion conv(fact_value, off_value); - di->setConverter(conv); - } + device_model::data_item::UnitConversion conv(fact_value, off_value); + di->setConverter(conv); + } catch (std::exception e) { LOG(error) << "Cannot convert factor " << factor << " or " << offset diff --git a/src/mtconnect/device_model/data_item/data_item.cpp b/src/mtconnect/device_model/data_item/data_item.cpp index b0596fbd1..f683d3876 100644 --- a/src/mtconnect/device_model/data_item/data_item.cpp +++ b/src/mtconnect/device_model/data_item/data_item.cpp @@ -201,6 +201,11 @@ namespace mtconnect { } } } + + if (const auto &init = maybeGet("InitialValue"); init) + { + m_initialValue = *init; + } if (const auto &init = maybeGet("InitialValue"); init) { diff --git a/src/mtconnect/device_model/data_item/data_item.hpp b/src/mtconnect/device_model/data_item/data_item.hpp index 8a7c6959c..7f62fdbd8 100644 --- a/src/mtconnect/device_model/data_item/data_item.hpp +++ b/src/mtconnect/device_model/data_item/data_item.hpp @@ -139,11 +139,11 @@ namespace mtconnect { /// @brief get the topic name leaf node for this data item /// @return the topic name const auto &getTopicName() const { return m_topicName; } - + /// @brief get the initial value if one is set /// @return optional initial value const auto &getInitialValue() const { return m_initialValue; } - + Category getCategory() const { return m_category; } Representation getRepresentation() const { return m_representation; } SpecialClass getSpecialClass() const { return m_specialClass; } diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 31aaf7fa6..288a79db6 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -3173,3 +3173,26 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_fa ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); } } + + +TEST_F(AgentTest, should_initialize_observaton_to_initial_value_when_available) +{ + m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.2", 4, true); + + auto device = m_agentTestHelper->getAgent()->getDeviceByName("LinuxCNC"); + ASSERT_TRUE(device); + + addAdapter(); + + { + PARSE_XML_RESPONSE("/current"); + ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:PartCount", "UNAVAILABLE"); + } + + m_agentTestHelper->m_adapter->processData("2024-01-22T20:00:00Z|avail|AVAILABLE"); + + { + PARSE_XML_RESPONSE("/current"); + ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:PartCount", "0"); + } +} From 0536124a9ce3b4d14aa013c79693e8a42f98981a Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sun, 28 Apr 2024 16:25:10 -0400 Subject: [PATCH 099/128] version 2.3.0.8 --- CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f5560bb92..9cd4564cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,13 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) +<<<<<<< HEAD set(AGENT_VERSION_BUILD 0) set(AGENT_VERSION_RC "RC2") +======= +set(AGENT_VERSION_BUILD 8) +set(AGENT_VERSION_RC "") +>>>>>>> de28136e (version 2.3.0.8) # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) From 03d255089e6a86f8b4833abac199ab78249e6584 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sun, 28 Apr 2024 22:48:37 -0400 Subject: [PATCH 100/128] merged main-dev --- src/mtconnect/agent.cpp | 4 ++-- src/mtconnect/device_model/data_item/data_item.cpp | 2 +- src/mtconnect/device_model/data_item/data_item.hpp | 4 ++-- test_package/agent_test.cpp | 3 +-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index af20d70e2..e842a7855 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -301,7 +301,7 @@ namespace mtconnect { { if (item.expired()) continue; - + auto di = item.lock(); if (di->hasInitialValue()) { @@ -309,7 +309,7 @@ namespace mtconnect { } } } - + std::lock_guard lock(m_circularBuffer); if (m_circularBuffer.addToBuffer(observation) != 0) { diff --git a/src/mtconnect/device_model/data_item/data_item.cpp b/src/mtconnect/device_model/data_item/data_item.cpp index f683d3876..50c0c601a 100644 --- a/src/mtconnect/device_model/data_item/data_item.cpp +++ b/src/mtconnect/device_model/data_item/data_item.cpp @@ -201,7 +201,7 @@ namespace mtconnect { } } } - + if (const auto &init = maybeGet("InitialValue"); init) { m_initialValue = *init; diff --git a/src/mtconnect/device_model/data_item/data_item.hpp b/src/mtconnect/device_model/data_item/data_item.hpp index 7f62fdbd8..8a7c6959c 100644 --- a/src/mtconnect/device_model/data_item/data_item.hpp +++ b/src/mtconnect/device_model/data_item/data_item.hpp @@ -139,11 +139,11 @@ namespace mtconnect { /// @brief get the topic name leaf node for this data item /// @return the topic name const auto &getTopicName() const { return m_topicName; } - + /// @brief get the initial value if one is set /// @return optional initial value const auto &getInitialValue() const { return m_initialValue; } - + Category getCategory() const { return m_category; } Representation getRepresentation() const { return m_representation; } SpecialClass getSpecialClass() const { return m_specialClass; } diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index 288a79db6..fee0c864d 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -3174,7 +3174,6 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_fa } } - TEST_F(AgentTest, should_initialize_observaton_to_initial_value_when_available) { m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.2", 4, true); @@ -3188,7 +3187,7 @@ TEST_F(AgentTest, should_initialize_observaton_to_initial_value_when_available) PARSE_XML_RESPONSE("/current"); ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:PartCount", "UNAVAILABLE"); } - + m_agentTestHelper->m_adapter->processData("2024-01-22T20:00:00Z|avail|AVAILABLE"); { From 56f9cf1a26407f540acadb04c665e2eb10c15fc9 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Sun, 28 Apr 2024 22:54:22 -0400 Subject: [PATCH 101/128] Removed extra character --- CMakeLists.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cd4564cf..2ea263a17 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,13 +2,8 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) -<<<<<<< HEAD set(AGENT_VERSION_BUILD 0) -set(AGENT_VERSION_RC "RC2") -======= -set(AGENT_VERSION_BUILD 8) -set(AGENT_VERSION_RC "") ->>>>>>> de28136e (version 2.3.0.8) +set(AGENT_VERSION_RC "RC2") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) From bee2907e268896c08af2ddccaa566b6d09f5be41 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 2 May 2024 16:56:23 -0400 Subject: [PATCH 102/128] Added initial websocket test --- src/mtconnect/sink/rest_sink/routing.hpp | 6 +- .../sink/rest_sink/websocket_session.hpp | 11 +- test_package/CMakeLists.txt | 1 + test_package/websockets_test.cpp | 246 ++++++++++++++++++ 4 files changed, 260 insertions(+), 4 deletions(-) create mode 100644 test_package/websockets_test.cpp diff --git a/src/mtconnect/sink/rest_sink/routing.hpp b/src/mtconnect/sink/rest_sink/routing.hpp index 0710f15b1..bfa584eeb 100644 --- a/src/mtconnect/sink/rest_sink/routing.hpp +++ b/src/mtconnect/sink/rest_sink/routing.hpp @@ -241,7 +241,11 @@ namespace mtconnect::sink::rest_sink { /// @brief Sets the command associated with this routing for use with websockets /// @param command the command - void command(const std::string &command) { m_command = command; } + auto &command(const std::string &command) + { + m_command = command; + return *this; + } protected: void pathParameters(std::string s) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 013d86016..84eda57e2 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -104,7 +104,14 @@ namespace mtconnect::sink::rest_sink { if (!m_isOpen) return; - auto ptr = derived().shared_ptr(); + m_isOpen = false; + + auto wptr = weak_from_this(); + std::shared_ptr ptr; + if (!wptr.expired()) + { + ptr = wptr.lock(); + } m_request.reset(); m_requests.clear(); @@ -117,8 +124,6 @@ namespace mtconnect::sink::rest_sink { } } closeStream(); - - m_isOpen = false; } void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index ec5961013..b0fb4c836 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -245,6 +245,7 @@ add_agent_test(qname FALSE entity) add_agent_test(file_cache FALSE sink/rest_sink) add_agent_test(http_server FALSE sink/rest_sink TRUE) +add_agent_test(websockets FALSE sink/rest_sink TRUE) add_agent_test(tls_http_server FALSE sink/rest_sink TRUE) add_agent_test(routing FALSE sink/rest_sink) diff --git a/test_package/websockets_test.cpp b/test_package/websockets_test.cpp new file mode 100644 index 000000000..0ca154420 --- /dev/null +++ b/test_package/websockets_test.cpp @@ -0,0 +1,246 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Ensure that gtest is the first header otherwise Windows raises an error +#include +// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "mtconnect/logging.hpp" +#include "mtconnect/sink/rest_sink/server.hpp" + +using namespace std; +using namespace mtconnect; +using namespace mtconnect::sink::rest_sink; + +namespace asio = boost::asio; +namespace beast = boost::beast; +namespace http = boost::beast::http; +using tcp = boost::asio::ip::tcp; +namespace websocket = beast::websocket; + +// main +int main(int argc, char* argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +class Client +{ +public: + Client(asio::io_context& ioc) : m_context(ioc), m_stream(ioc) {} + + ~Client() { close(); } + + void fail(beast::error_code ec, char const* what) + { + LOG(error) << what << ": " << ec.message() << "\n"; + m_done = true; + m_ec = ec; + } + + void connect(unsigned short port, asio::yield_context yield) + { + beast::error_code ec; + + // These objects perform our I/O + tcp::endpoint server(asio::ip::address_v4::from_string("127.0.0.1"), port); + + // Make the connection on the IP address we get from a lookup + beast::get_lowest_layer(m_stream).async_connect(server, yield[ec]); + + if (ec) + { + return fail(ec, "connect"); + } + + m_stream.set_option(websocket::stream_base::timeout::suggested(beast::role_type::client)); + + m_stream.set_option(websocket::stream_base::decorator([](websocket::request_type& req) { + req.set(http::field::user_agent, + std::string(BOOST_BEAST_VERSION_STRING) + " websocket-client"); + })); + + string host = "127.0.0.1:" + std::to_string(port); + m_stream.async_handshake(host, "/", yield[ec]); + + if (ec) + { + return fail(ec, "connect"); + } + + m_connected = true; + + m_stream.async_read(m_buffer, beast::bind_front_handler(&Client::onRead, this)); + } + + void onRead(beast::error_code ec, std::size_t bytes_transferred) + { + m_result = beast::buffers_to_string(m_buffer.data()); + m_buffer.consume(m_buffer.size()); + + m_done = true; + } + + void request(const string& payload, asio::yield_context yield) + { + cout << "spawnRequest: done: false" << endl; + m_done = false; + beast::error_code ec; + + m_stream.async_write(asio::buffer(payload), yield[ec]); + + waitFor(2s, [this]() { return m_done; }); + } + + template + bool waitFor(const chrono::duration& time, function pred) + { + boost::asio::steady_timer timer(m_context); + timer.expires_from_now(time); + bool timeout = false; + timer.async_wait([&timeout](boost::system::error_code ec) { + if (!ec) + { + timeout = true; + } + }); + + while (!timeout && !pred()) + { + m_context.run_for(500ms); + } + timer.cancel(); + + return pred(); + } + + void close() + { + beast::error_code ec; + + // Gracefully close the socket + m_stream.next_layer().shutdown(tcp::socket::shutdown_both, ec); + } + + bool m_connected {false}; + int m_status; + std::string m_result; + asio::io_context& m_context; + bool m_done {false}; + websocket::stream m_stream; + beast::flat_buffer m_buffer; + boost::beast::error_code m_ec; + beast::flat_buffer m_b; + int m_count {0}; +}; + +class WebsocketsTest : public testing::Test +{ +protected: + void SetUp() override + { + using namespace mtconnect::configuration; + m_server = make_unique(m_context, ConfigOptions {{Port, 0}, {ServerIp, "127.0.0.1"s}}); + } + + void createServer(const ConfigOptions& options) + { + using namespace mtconnect::configuration; + ConfigOptions opts {{Port, 0}, {ServerIp, "127.0.0.1"s}}; + opts.merge(ConfigOptions(options)); + m_server = make_unique(m_context, opts); + } + + void start() + { + m_server->start(); + while (!m_server->isListening()) + m_context.run_one(); + m_client = make_unique(m_context); + } + + void startClient() + { + m_client->m_connected = false; + asio::spawn(m_context, + std::bind(&Client::connect, m_client.get(), + static_cast(m_server->getPort()), std::placeholders::_1)); + + m_client->waitFor(1s, [this]() { return m_client->m_connected; }); + } + + void TearDown() override + { + m_server.reset(); + m_client.reset(); + } + + asio::io_context m_context; + unique_ptr m_server; + unique_ptr m_client; +}; + +TEST_F(WebsocketsTest, should_connect_to_server) +{ + start(); + startClient(); + + ASSERT_TRUE(m_client->m_connected); +} + +TEST_F(WebsocketsTest, should_make_simple_request) +{ + weak_ptr savedSession; + + auto probe = [&](SessionPtr session, RequestPtr request) -> bool { + savedSession = session; + ResponsePtr resp = make_unique(status::ok); + resp->m_body = "All Devices for "s + *request->m_requestId; + resp->m_requestId = request->m_requestId; + session->writeResponse(std::move(resp), []() { cout << "Written" << endl; }); + return true; + }; + + m_server->addRouting({boost::beast::http::verb::get, "/probe", probe}).command("probe"); + m_server->addCommands(); + + start(); + startClient(); + + asio::spawn(m_context, std::bind(&Client::request, m_client.get(), + "{\"id\":\"1\",\"request\":\"probe\"}"s, std::placeholders::_1)); + + m_client->waitFor(2s, [this]() { return m_client->m_done; }); + + ASSERT_TRUE(m_client->m_done); + ASSERT_EQ("All Devices for 1", m_client->m_result); +} From d6ffc00f070cd9e9aa5201e1a0d8e17007a838f8 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 2 May 2024 21:15:39 -0400 Subject: [PATCH 103/128] cast to parameter value --- .../sink/rest_sink/websocket_session.hpp | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 84eda57e2..34ee931e6 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -362,10 +362,12 @@ namespace mtconnect::sink::rest_sink { // Skip nulls break; case rapidjson::kFalseType: - request->m_parameters.emplace(make_pair(it.name.GetString(), false)); + request->m_parameters.emplace( + make_pair(it.name.GetString(), ParameterValue(bool(false)))); break; case rapidjson::kTrueType: - request->m_parameters.emplace(make_pair(it.name.GetString(), true)); + request->m_parameters.emplace( + make_pair(it.name.GetString(), ParameterValue(bool(true)))); break; case rapidjson::kObjectType: break; @@ -373,24 +375,25 @@ namespace mtconnect::sink::rest_sink { break; case rapidjson::kStringType: request->m_parameters.emplace( - make_pair(it.name.GetString(), string(it.value.GetString()))); + make_pair(it.name.GetString(), ParameterValue(it.value.GetString()))); break; case rapidjson::kNumberType: if (it.value.Is()) - request->m_parameters.emplace(make_pair(it.name.GetString(), it.value.Get())); + request->m_parameters.emplace( + make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); else if (it.value.Is()) request->m_parameters.emplace( - make_pair(it.name.GetString(), it.value.Get())); + make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); else if (it.value.Is()) - request->m_parameters.emplace( - make_pair(it.name.GetString(), (uint64_t)it.value.Get())); + request->m_parameters.emplace(make_pair( + it.name.GetString(), ParameterValue((uint64_t)it.value.Get()))); else if (it.value.Is()) request->m_parameters.emplace( - make_pair(it.name.GetString(), it.value.Get())); + make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); else if (it.value.Is()) request->m_parameters.emplace( - make_pair(it.name.GetString(), it.value.Get())); + make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); break; } From 491e9b2cb6a5ec7d0dfe0350bd70ff8d1bc879c5 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 2 May 2024 22:48:40 -0400 Subject: [PATCH 104/128] windows port of websockets --- agent_lib/CMakeLists.txt | 2 +- .../sink/rest_sink/websocket_session.hpp | 36 +++++++++++-------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index 5b4ae0a40..66fba701e 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -333,8 +333,8 @@ if(MSVC) # The modules including Beast required the /bigobj option in Windows set_property(SOURCE + "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.cpp" "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" - "${SOURCE_DIR}/sink/mqtt_sink/mqtt2_service.cpp" "${SOURCE_DIR}/sink/rest_sink/session_impl.cpp" "${SOURCE_DIR}/source/adapter/mqtt/mqtt_adapter.cpp" "${SOURCE_DIR}/source/adapter/agent_adapter/agent_adapter.cpp" diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 34ee931e6..7a84bfbce 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -352,7 +352,15 @@ namespace mtconnect::sink::rest_sink { request->m_verb = beast::http::verb::get; request->m_parameters.clear(); +#ifdef GetObject +#define __GOSave__ GetObject +#undef GetObject +#endif + const auto &object = doc.GetObject(); +#ifdef __GOSave__ +#define GetObject __GOSave__ +#endif for (auto &it : object) { @@ -363,11 +371,11 @@ namespace mtconnect::sink::rest_sink { break; case rapidjson::kFalseType: request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(bool(false)))); + make_pair(string(it.name.GetString()), ParameterValue(false))); break; case rapidjson::kTrueType: request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(bool(true)))); + make_pair(string(it.name.GetString()), ParameterValue(true))); break; case rapidjson::kObjectType: break; @@ -375,25 +383,25 @@ namespace mtconnect::sink::rest_sink { break; case rapidjson::kStringType: request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(it.value.GetString()))); + make_pair(it.name.GetString(), ParameterValue(string(it.value.GetString())))); break; case rapidjson::kNumberType: - if (it.value.Is()) + if (it.value.IsInt()) + request->m_parameters.emplace( + make_pair(it.name.GetString(), ParameterValue(it.value.GetInt()))); + else if (it.value.IsUint()) request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); - else if (it.value.Is()) + make_pair(it.name.GetString(), ParameterValue(uint64_t(it.value.GetUint())))); + else if (it.value.IsInt64()) request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); - else if (it.value.Is()) - request->m_parameters.emplace(make_pair( - it.name.GetString(), ParameterValue((uint64_t)it.value.Get()))); - else if (it.value.Is()) + make_pair(it.name.GetString(), ParameterValue(uint64_t(it.value.GetInt64())))); + else if (it.value.IsUint64()) request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); - else if (it.value.Is()) + make_pair(it.name.GetString(), ParameterValue(it.value.GetUint64()))); + else if (it.value.IsDouble()) request->m_parameters.emplace( - make_pair(it.name.GetString(), ParameterValue(it.value.Get()))); + make_pair(it.name.GetString(), ParameterValue(double(it.value.GetDouble())))); break; } From ace5a2fcb00a0193656c76c5748bfa3660ca1f95 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 3 May 2024 04:44:30 -0400 Subject: [PATCH 105/128] removed named scope from websocket session --- src/mtconnect/sink/rest_sink/websocket_session.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index 7a84bfbce..c0bd12a2a 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -100,7 +100,7 @@ namespace mtconnect::sink::rest_sink { void close() override { - NAMED_SCOPE("PlainWebsocketSession::close"); + //NAMED_SCOPE("PlainWebsocketSession::close"); if (!m_isOpen) return; @@ -128,7 +128,7 @@ namespace mtconnect::sink::rest_sink { void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { - NAMED_SCOPE("WebsocketSession::writeResponse"); + //NAMED_SCOPE("WebsocketSession::writeResponse"); if (!response->m_requestId) { boost::system::error_code ec; @@ -140,7 +140,7 @@ namespace mtconnect::sink::rest_sink { void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override { - NAMED_SCOPE("WebsocketSession::writeFailureResponse"); + //NAMED_SCOPE("WebsocketSession::writeFailureResponse"); writeChunk(response->m_body, complete, response->m_requestId); } @@ -175,7 +175,7 @@ namespace mtconnect::sink::rest_sink { void writeChunk(const std::string &chunk, Complete complete, std::optional requestId = std::nullopt) override { - NAMED_SCOPE("WebsocketSession::writeChunk"); + //NAMED_SCOPE("WebsocketSession::writeChunk"); if (!derived().stream().is_open()) { @@ -219,7 +219,7 @@ namespace mtconnect::sink::rest_sink { void send(const std::string body, Complete complete, const std::string &requestId) { - NAMED_SCOPE("WebsocketSession::send"); + //NAMED_SCOPE("WebsocketSession::send"); using namespace std::placeholders; @@ -255,7 +255,7 @@ namespace mtconnect::sink::rest_sink { void sent(beast::error_code ec, std::size_t len, const std::string &id) { - NAMED_SCOPE("WebsocketSession::sent"); + //NAMED_SCOPE("WebsocketSession::sent"); if (ec) { @@ -310,7 +310,7 @@ namespace mtconnect::sink::rest_sink { void onRead(beast::error_code ec, std::size_t len) { - NAMED_SCOPE("PlainWebsocketSession::onRead"); + //NAMED_SCOPE("PlainWebsocketSession::onRead"); if (ec) return fail(boost::beast::http::status::internal_server_error, "shutdown", ec); From c159a55bec3cbd7576e270499e4dd31d5d516e71 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 3 May 2024 05:49:44 -0400 Subject: [PATCH 106/128] Added BOOST_USE_WINAPI_VERSION for boost 1.84 --- conan/profiles/vs32 | 1 + conan/profiles/vs32debug | 1 + conan/profiles/vs32shared | 1 + conanfile.py | 2 +- src/mtconnect/sink/rest_sink/websocket_session.hpp | 14 +++++++------- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/conan/profiles/vs32 b/conan/profiles/vs32 index 8b20a3bfe..74614a5bd 100644 --- a/conan/profiles/vs32 +++ b/conan/profiles/vs32 @@ -3,6 +3,7 @@ include(default) [settings] compiler=msvc compiler.cppstd=17 +winver=0x0600 arch=x86 compiler.runtime=static compiler.runtime_type=Release diff --git a/conan/profiles/vs32debug b/conan/profiles/vs32debug index 505fc71bc..06bbf8be0 100644 --- a/conan/profiles/vs32debug +++ b/conan/profiles/vs32debug @@ -3,6 +3,7 @@ include(default) [settings] compiler=msvc compiler.cppstd=17 +winver=0x0600 arch=x86 compiler.runtime=static compiler.runtime_type=Debug diff --git a/conan/profiles/vs32shared b/conan/profiles/vs32shared index 52ac0b1e4..129f98418 100644 --- a/conan/profiles/vs32shared +++ b/conan/profiles/vs32shared @@ -4,6 +4,7 @@ include(default) compiler=msvc compiler.cppstd=17 arch=x86 +winver=0x0600 compiler.runtime=dynamic compiler.runtime_type=Release build_type=Release diff --git a/conanfile.py b/conanfile.py index 745600d77..4dea1d979 100644 --- a/conanfile.py +++ b/conanfile.py @@ -139,7 +139,7 @@ def configure(self): if self.options.shared: self.options["boost/*"].shared = True self.package_type = "shared-library" - + if is_msvc(self): self.options["boost/*"].extra_b2_flags = ("define=BOOST_USE_WINAPI_VERSION=" + str(self.options.winver)) diff --git a/src/mtconnect/sink/rest_sink/websocket_session.hpp b/src/mtconnect/sink/rest_sink/websocket_session.hpp index c0bd12a2a..7a84bfbce 100644 --- a/src/mtconnect/sink/rest_sink/websocket_session.hpp +++ b/src/mtconnect/sink/rest_sink/websocket_session.hpp @@ -100,7 +100,7 @@ namespace mtconnect::sink::rest_sink { void close() override { - //NAMED_SCOPE("PlainWebsocketSession::close"); + NAMED_SCOPE("PlainWebsocketSession::close"); if (!m_isOpen) return; @@ -128,7 +128,7 @@ namespace mtconnect::sink::rest_sink { void writeResponse(ResponsePtr &&response, Complete complete = nullptr) override { - //NAMED_SCOPE("WebsocketSession::writeResponse"); + NAMED_SCOPE("WebsocketSession::writeResponse"); if (!response->m_requestId) { boost::system::error_code ec; @@ -140,7 +140,7 @@ namespace mtconnect::sink::rest_sink { void writeFailureResponse(ResponsePtr &&response, Complete complete = nullptr) override { - //NAMED_SCOPE("WebsocketSession::writeFailureResponse"); + NAMED_SCOPE("WebsocketSession::writeFailureResponse"); writeChunk(response->m_body, complete, response->m_requestId); } @@ -175,7 +175,7 @@ namespace mtconnect::sink::rest_sink { void writeChunk(const std::string &chunk, Complete complete, std::optional requestId = std::nullopt) override { - //NAMED_SCOPE("WebsocketSession::writeChunk"); + NAMED_SCOPE("WebsocketSession::writeChunk"); if (!derived().stream().is_open()) { @@ -219,7 +219,7 @@ namespace mtconnect::sink::rest_sink { void send(const std::string body, Complete complete, const std::string &requestId) { - //NAMED_SCOPE("WebsocketSession::send"); + NAMED_SCOPE("WebsocketSession::send"); using namespace std::placeholders; @@ -255,7 +255,7 @@ namespace mtconnect::sink::rest_sink { void sent(beast::error_code ec, std::size_t len, const std::string &id) { - //NAMED_SCOPE("WebsocketSession::sent"); + NAMED_SCOPE("WebsocketSession::sent"); if (ec) { @@ -310,7 +310,7 @@ namespace mtconnect::sink::rest_sink { void onRead(beast::error_code ec, std::size_t len) { - //NAMED_SCOPE("PlainWebsocketSession::onRead"); + NAMED_SCOPE("PlainWebsocketSession::onRead"); if (ec) return fail(boost::beast::http::status::internal_server_error, "shutdown", ec); From 27633ac9b99763e51fd206467dc1fc3ec92c9743 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 3 May 2024 10:17:57 -0400 Subject: [PATCH 107/128] added boost windows api version for windows 1.84 porting --- conan/profiles/vs32 | 4 ++-- conan/profiles/vs32debug | 3 ++- conan/profiles/vs32shared | 2 +- conanfile.py | 3 +++ 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/conan/profiles/vs32 b/conan/profiles/vs32 index 74614a5bd..fb406b017 100644 --- a/conan/profiles/vs32 +++ b/conan/profiles/vs32 @@ -3,10 +3,10 @@ include(default) [settings] compiler=msvc compiler.cppstd=17 -winver=0x0600 arch=x86 compiler.runtime=static compiler.runtime_type=Release build_type=Release - +[options] +winver=0x0600 diff --git a/conan/profiles/vs32debug b/conan/profiles/vs32debug index 06bbf8be0..54344e405 100644 --- a/conan/profiles/vs32debug +++ b/conan/profiles/vs32debug @@ -3,9 +3,10 @@ include(default) [settings] compiler=msvc compiler.cppstd=17 -winver=0x0600 arch=x86 compiler.runtime=static compiler.runtime_type=Debug build_type=Debug +[options] +winver=0x0600 diff --git a/conan/profiles/vs32shared b/conan/profiles/vs32shared index 129f98418..d30b8f54c 100644 --- a/conan/profiles/vs32shared +++ b/conan/profiles/vs32shared @@ -4,7 +4,6 @@ include(default) compiler=msvc compiler.cppstd=17 arch=x86 -winver=0x0600 compiler.runtime=dynamic compiler.runtime_type=Release build_type=Release @@ -12,3 +11,4 @@ build_type=Release [options] shared=True +winver=0x0600 diff --git a/conanfile.py b/conanfile.py index 4dea1d979..8df4cd46f 100644 --- a/conanfile.py +++ b/conanfile.py @@ -139,6 +139,9 @@ def configure(self): if self.options.shared: self.options["boost/*"].shared = True self.package_type = "shared-library" + + if is_msvc(self): + self.options["boost/*"].extra_b2_flags = ("define=BOOST_USE_WINAPI_VERSION=" + str(self.options.winver)) if is_msvc(self): self.options["boost/*"].extra_b2_flags = ("define=BOOST_USE_WINAPI_VERSION=" + str(self.options.winver)) From 192698bb414722038e451d2b280843295a031046 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Fri, 3 May 2024 11:45:33 -0400 Subject: [PATCH 108/128] removed legacy mqtt service --- agent_lib/CMakeLists.txt | 3 - src/mtconnect/configuration/agent_config.cpp | 2 - .../sink/mqtt_sink/mqtt_legacy_service.cpp | 197 ------ .../sink/mqtt_sink/mqtt_legacy_service.hpp | 107 --- src/mtconnect/sink/rest_sink/rest_service.cpp | 4 +- test_package/CMakeLists.txt | 1 - test_package/agent_test_helper.hpp | 23 - test_package/mqtt_isolated_test.cpp | 2 +- test_package/mqtt_legacy_sink_test.cpp | 630 ------------------ test_package/mqtt_sink_test.cpp | 17 +- 10 files changed, 12 insertions(+), 974 deletions(-) delete mode 100644 src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp delete mode 100644 src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp delete mode 100644 test_package/mqtt_legacy_sink_test.cpp diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index 66fba701e..dc8316917 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -244,12 +244,10 @@ set(AGENT_SOURCES # src/sink/mqtt_sink HEADER_FILE_ONLY - "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.hpp" "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.hpp" #src/sink/mqtt_sink SOURCE_FILES_ONLY - "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.cpp" "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" # src/sink/rest_sink HEADER_FILE_ONLY @@ -333,7 +331,6 @@ if(MSVC) # The modules including Beast required the /bigobj option in Windows set_property(SOURCE - "${SOURCE_DIR}/sink/mqtt_sink/mqtt_legacy_service.cpp" "${SOURCE_DIR}/sink/mqtt_sink/mqtt_service.cpp" "${SOURCE_DIR}/sink/rest_sink/session_impl.cpp" "${SOURCE_DIR}/source/adapter/mqtt/mqtt_adapter.cpp" diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index e9c22d4be..9052398d8 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -58,7 +58,6 @@ #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/device_model/device.hpp" #include "mtconnect/printer/xml_printer.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" #include "mtconnect/sink/mqtt_sink/mqtt_service.hpp" #include "mtconnect/sink/rest_sink/rest_service.hpp" #include "mtconnect/source/adapter/agent_adapter/agent_adapter.hpp" @@ -112,7 +111,6 @@ namespace mtconnect::configuration { bool success = false; - sink::mqtt_sink::MqttLegacyService::registerFactory(m_sinkFactory); sink::mqtt_sink::MqttService::registerFactory(m_sinkFactory); sink::rest_sink::RestService::registerFactory(m_sinkFactory); adapter::shdr::ShdrAdapter::registerFactory(m_sourceFactory); diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp deleted file mode 100644 index 46aea8a12..000000000 --- a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.cpp +++ /dev/null @@ -1,197 +0,0 @@ -// -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#include "mqtt_legacy_service.hpp" - -#include "mtconnect/configuration/config_options.hpp" -#include "mtconnect/entity/entity.hpp" -#include "mtconnect/entity/factory.hpp" -#include "mtconnect/entity/json_parser.hpp" -#include "mtconnect/mqtt/mqtt_client_impl.hpp" -#include "mtconnect/printer/json_printer.hpp" - -using ptree = boost::property_tree::ptree; - -using namespace std; -using namespace mtconnect::asset; - -namespace asio = boost::asio; -namespace config = ::mtconnect::configuration; - -namespace mtconnect { - namespace sink { - namespace mqtt_sink { - // get obeservation in - // create a json printer - // call print - - MqttLegacyService::MqttLegacyService(boost::asio::io_context &context, - sink::SinkContractPtr &&contract, - const ConfigOptions &options, const ptree &config) - : Sink("MqttLegacyService", std::move(contract)), m_context(context), m_options(options) - { - auto jsonPrinter = dynamic_cast(m_sinkContract->getPrinter("json")); - m_jsonPrinter = make_unique(jsonPrinter->getJsonVersion()); - - GetOptions(config, m_options, options); - AddOptions(config, m_options, - {{configuration::ProbeTopic, string()}, - {configuration::MqttCaCert, string()}, - {configuration::MqttPrivateKey, string()}, - {configuration::MqttCert, string()}, - {configuration::MqttUserName, string()}, - {configuration::MqttPassword, string()}, - {configuration::MqttClientId, string()}}); - AddDefaultedOptions(config, m_options, - {{configuration::MqttHost, "127.0.0.1"s}, - {configuration::DeviceTopic, "MTConnect/Device/"s}, - {configuration::AssetTopic, "MTConnect/Asset/"s}, - {configuration::ObservationTopic, "MTConnect/Observation/"s}, - {configuration::MqttPort, 1883}, - {configuration::MqttTls, false}}); - - auto clientHandler = make_unique(); - clientHandler->m_connected = [this](shared_ptr client) { - // Publish latest devices, assets, and observations - auto &circ = m_sinkContract->getCircularBuffer(); - std::lock_guard lock(circ); - client->connectComplete(); - - for (auto &dev : m_sinkContract->getDevices()) - { - publish(dev); - } - - auto obsList {circ.getLatest().getObservations()}; - for (auto &obs : obsList) - { - observation::ObservationPtr p {obs.second}; - publish(p); - } - - AssetList list; - m_sinkContract->getAssetStorage()->getAssets(list, 100000); - for (auto &asset : list) - { - publish(asset); - } - }; - - m_devicePrefix = GetOption(m_options, configuration::ProbeTopic) - .value_or(get(m_options[configuration::DeviceTopic])); - m_assetPrefix = get(m_options[configuration::AssetTopic]); - m_observationPrefix = get(m_options[configuration::ObservationTopic]); - - if (IsOptionSet(m_options, configuration::MqttTls)) - { - m_client = make_shared(m_context, m_options, std::move(clientHandler)); - } - else - { - m_client = make_shared(m_context, m_options, std::move(clientHandler)); - } - } - - void MqttLegacyService::start() - { - // mqtt client side not a server side... - if (!m_client) - return; - - m_client->start(); - } - - void MqttLegacyService::stop() - { - // stop client side - if (m_client) - m_client->stop(); - } - - std::shared_ptr MqttLegacyService::getClient() { return m_client; } - - bool MqttLegacyService::publish(observation::ObservationPtr &observation) - { - // get the data item from observation - if (observation->isOrphan()) - return false; - - DataItemPtr dataItem = observation->getDataItem(); - - auto topic = m_observationPrefix + dataItem->getTopic(); // client asyn topic - auto content = dataItem->getTopicName(); // client asyn content - - // We may want to use the observation from the checkpoint. - string doc; - if (observation->getDataItem()->isCondition()) - { - doc = m_jsonPrinter->print(observation); - } - else - { - doc = m_jsonPrinter->printEntity(observation); - } - - if (m_client) - m_client->publish(topic, doc); - - return true; - } - - bool MqttLegacyService::publish(device_model::DevicePtr device) - { - auto topic = m_devicePrefix + *device->getUuid(); - auto doc = m_jsonPrinter->print(device); - - stringstream buffer; - buffer << doc; - - if (m_client) - m_client->publish(topic, buffer.str()); - - return true; - } - - bool MqttLegacyService::publish(asset::AssetPtr asset) - { - auto topic = m_assetPrefix + get(asset->getIdentity()); - auto doc = m_jsonPrinter->print(asset); - - stringstream buffer; - buffer << doc; - - if (m_client) - m_client->publish(topic, buffer.str()); - - return true; - } - - // Register the service with the sink factory - void MqttLegacyService::registerFactory(SinkFactory &factory) - { - factory.registerFactory( - "MqttLegacyService", - [](const std::string &name, boost::asio::io_context &io, SinkContractPtr &&contract, - const ConfigOptions &options, const boost::property_tree::ptree &block) -> SinkPtr { - auto sink = - std::make_shared(io, std::move(contract), options, block); - return sink; - }); - } - } // namespace mqtt_sink - } // namespace sink -} // namespace mtconnect diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp deleted file mode 100644 index ab84d97d5..000000000 --- a/src/mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp +++ /dev/null @@ -1,107 +0,0 @@ -// -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -#pragma once - -#include "boost/asio/io_context.hpp" -#include - -#include "mtconnect/buffer/checkpoint.hpp" -#include "mtconnect/config.hpp" -#include "mtconnect/configuration/agent_config.hpp" -#include "mtconnect/entity/json_printer.hpp" -#include "mtconnect/mqtt/mqtt_client.hpp" -#include "mtconnect/observation/observation.hpp" -#include "mtconnect/printer/printer.hpp" -#include "mtconnect/printer/xml_printer_helper.hpp" -#include "mtconnect/sink/sink.hpp" -#include "mtconnect/utilities.hpp" - -using namespace std; -using namespace mtconnect::entity; -using namespace mtconnect::mqtt_client; - -namespace mtconnect { - class XmlPrinter; - - namespace sink { - - /// @brief MTConnect Mqtt implemention namespace - - namespace mqtt_sink { - class AGENT_LIB_API MqttLegacyService : public sink::Sink - { - // dynamic loading of sink - - public: - /// @brief Create a Mqtt Service sink - /// @param context the boost asio io_context - /// @param contract the Sink Contract from the agent - /// @param options configuration options - /// @param config additional configuration options if specified directly as a sink - MqttLegacyService(boost::asio::io_context &context, sink::SinkContractPtr &&contract, - const ConfigOptions &options, const boost::property_tree::ptree &config); - - ~MqttLegacyService() = default; - - // Sink Methods - /// @brief Start the Mqtt service - void start() override; - - /// @brief Shutdown the Mqtt service - void stop() override; - - /// @brief Receive an observation - /// @param observation shared pointer to the observation - /// @return `true` if the publishing was successful - bool publish(observation::ObservationPtr &observation) override; - - /// @brief Receive an asset - /// @param asset shared point to the asset - /// @return `true` if successful - bool publish(asset::AssetPtr asset) override; - - /// @brief Receive a device - /// @param device shared pointer to the device - /// @return `true` if successful - bool publish(device_model::DevicePtr device) override; - - /// @brief Register the Sink factory to create this sink - /// @param factory - static void registerFactory(SinkFactory &factory); - - /// @brief gets a Mqtt Client - /// @return MqttClient - std::shared_ptr getClient(); - - /// @brief Mqtt Client is Connected or not - /// @return `true` when the client was connected - bool isConnected() { return m_client && m_client->isConnected(); } - - protected: - std::string m_devicePrefix; - std::string m_assetPrefix; - std::string m_observationPrefix; - - boost::asio::io_context &m_context; - ConfigOptions m_options; - std::unique_ptr m_jsonPrinter; - std::shared_ptr m_client; - }; - } // namespace mqtt_sink - } // namespace sink -} // namespace mtconnect diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 37e326cdc..914f8b3da 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -531,7 +531,7 @@ namespace mtconnect { auto handler = [&](SessionPtr session, RequestPtr request) -> bool { auto removed = *request->parameter("removed"); auto count = *request->parameter("count"); - auto pretty = *request->parameter("pretty"); + auto pretty = request->parameter("pretty").value_or(false); auto format = request->parameter("format"); auto printer = getPrinter(request->m_accepts, format); @@ -548,7 +548,7 @@ namespace mtconnect { if (asset) { auto format = request->parameter("format"); - auto pretty = *request->parameter("pretty"); + auto pretty = request->parameter("pretty").value_or(false); auto printer = m_sinkContract->getPrinter(acceptFormat(request->m_accepts, format)); list ids; diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index b0fb4c836..05427a32d 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -250,7 +250,6 @@ add_agent_test(tls_http_server FALSE sink/rest_sink TRUE) add_agent_test(routing FALSE sink/rest_sink) add_agent_test(mqtt_isolated FALSE mqtt_isolated TRUE) -add_agent_test(mqtt_legacy_sink FALSE sink/mqtt_legacy_sink TRUE) add_agent_test(mqtt_sink FALSE sink/mqtt_sink TRUE) add_agent_test(json_printer_asset TRUE json) diff --git a/test_package/agent_test_helper.hpp b/test_package/agent_test_helper.hpp index 4d16eb475..16c7a5cf7 100644 --- a/test_package/agent_test_helper.hpp +++ b/test_package/agent_test_helper.hpp @@ -29,7 +29,6 @@ #include "mtconnect/configuration/agent_config.hpp" #include "mtconnect/configuration/config_options.hpp" #include "mtconnect/pipeline/pipeline.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" #include "mtconnect/sink/mqtt_sink/mqtt_service.hpp" #include "mtconnect/sink/rest_sink/response.hpp" #include "mtconnect/sink/rest_sink/rest_service.hpp" @@ -124,7 +123,6 @@ class AgentTestHelper ~AgentTestHelper() { - m_mqttLegacyService.reset(); m_mqttService.reset(); m_restService.reset(); m_adapter.reset(); @@ -171,15 +169,6 @@ class AgentTestHelper return rest; } - std::shared_ptr getMqttLegacyService() - { - using namespace mtconnect; - sink::SinkPtr sink = m_agent->findSink("MqttLegacyService"); - std::shared_ptr mqtt = - std::dynamic_pointer_cast(sink); - return mqtt; - } - std::shared_ptr getMqttService() { using namespace mtconnect; @@ -199,7 +188,6 @@ class AgentTestHelper using ptree = boost::property_tree::ptree; sink::rest_sink::RestService::registerFactory(m_sinkFactory); - sink::mqtt_sink::MqttLegacyService::registerFactory(m_sinkFactory); sink::mqtt_sink::MqttService::registerFactory(m_sinkFactory); source::adapter::shdr::ShdrAdapter::registerFactory(m_sourceFactory); @@ -232,16 +220,6 @@ class AgentTestHelper m_restService = std::dynamic_pointer_cast(sink); m_agent->addSink(m_restService); - if (HasOption(options, "MqttLegacySink")) - { - auto mqttContract = m_agent->makeSinkContract(); - mqttContract->m_pipelineContext = m_context; - auto mqttsink = m_sinkFactory.make("MqttLegacyService", "MqttLegacyService", m_ioContext, - std::move(mqttContract), options, ptree {}); - m_mqttLegacyService = std::dynamic_pointer_cast(mqttsink); - m_agent->addSink(m_mqttLegacyService); - } - if (HasOption(options, "MqttSink")) { auto mqttContract = m_agent->makeSinkContract(); @@ -324,7 +302,6 @@ class AgentTestHelper mhttp::Server *m_server {nullptr}; std::shared_ptr m_context; std::shared_ptr m_adapter; - std::shared_ptr m_mqttLegacyService; std::shared_ptr m_mqttService; std::shared_ptr m_restService; std::shared_ptr m_loopback; diff --git a/test_package/mqtt_isolated_test.cpp b/test_package/mqtt_isolated_test.cpp index 4e7cbc566..9789436c5 100644 --- a/test_package/mqtt_isolated_test.cpp +++ b/test_package/mqtt_isolated_test.cpp @@ -181,7 +181,7 @@ class MqttIsolatedUnitTest : public testing::Test std::unique_ptr m_jsonPrinter; std::shared_ptr m_server; std::shared_ptr m_client; - std::shared_ptr m_service; + std::shared_ptr m_service; std::unique_ptr m_agentTestHelper; uint16_t m_port {0}; }; diff --git a/test_package/mqtt_legacy_sink_test.cpp b/test_package/mqtt_legacy_sink_test.cpp deleted file mode 100644 index 4647c924e..000000000 --- a/test_package/mqtt_legacy_sink_test.cpp +++ /dev/null @@ -1,630 +0,0 @@ -// -// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) -// All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// - -/// @file -/// Test MQTT 1 Service - -// Ensure that gtest is the first header otherwise Windows raises an error -#include -// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) - -#include - -#include - -#include "agent_test_helper.hpp" -#include "mtconnect/buffer/checkpoint.hpp" -#include "mtconnect/device_model/data_item/data_item.hpp" -#include "mtconnect/entity/entity.hpp" -#include "mtconnect/entity/json_parser.hpp" -#include "mtconnect/mqtt/mqtt_client_impl.hpp" -#include "mtconnect/mqtt/mqtt_server_impl.hpp" -#include "mtconnect/printer//json_printer.hpp" -#include "mtconnect/sink/mqtt_sink/mqtt_legacy_service.hpp" - -using namespace std; -using namespace mtconnect; -using namespace mtconnect::device_model::data_item; -using namespace mtconnect::sink::mqtt_sink; -using namespace mtconnect::asset; -using namespace mtconnect::configuration; - -// main -int main(int argc, char *argv[]) -{ - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} - -using json = nlohmann::json; - -class MqttSinkTest : public testing::Test -{ -protected: - void SetUp() override - { - m_agentTestHelper = make_unique(); - m_jsonPrinter = std::make_unique(2, true); - } - - void TearDown() override - { - const auto agent = m_agentTestHelper->getAgent(); - if (agent) - { - m_agentTestHelper->getAgent()->stop(); - m_agentTestHelper->m_ioContext.run_for(100ms); - } - if (m_client) - { - m_client->stop(); - m_agentTestHelper->m_ioContext.run_for(100ms); - m_client.reset(); - } - if (m_server) - { - m_server->stop(); - m_agentTestHelper->m_ioContext.run_for(500ms); - m_server.reset(); - } - m_agentTestHelper.reset(); - m_jsonPrinter.reset(); - } - - void createAgent(std::string testFile = {}, ConfigOptions options = {}) - { - if (testFile == "") - testFile = "/samples/test_config.xml"; - - ConfigOptions opts(options); - MergeOptions(opts, {{"MqttLegacySink", true}, - {configuration::MqttPort, m_port}, - {configuration::MqttHost, "127.0.0.1"s}}); - m_agentTestHelper->createAgent(testFile, 8, 4, "2.0", 25, false, true, opts); - addAdapter(); - - m_agentTestHelper->getAgent()->start(); - } - - void createServer(const ConfigOptions &options) - { - using namespace mtconnect::configuration; - ConfigOptions opts(options); - MergeOptions(opts, {{ServerIp, "127.0.0.1"s}, - {MqttPort, 0}, - {MqttTls, false}, - {AutoAvailable, false}, - {RealTime, false}}); - - m_server = - make_shared(m_agentTestHelper->m_ioContext, opts); - } - - template - bool waitFor(const chrono::duration &time, function pred) - { - boost::asio::steady_timer timer(m_agentTestHelper->m_ioContext); - timer.expires_from_now(time); - bool timeout = false; - timer.async_wait([&timeout](boost::system::error_code ec) { - if (!ec) - { - timeout = true; - } - }); - - while (!timeout && !pred()) - { - m_agentTestHelper->m_ioContext.run_for(100ms); - } - timer.cancel(); - - return pred(); - } - - void startServer() - { - if (m_server) - { - bool start = m_server->start(); - if (start) - { - m_port = m_server->getPort(); - m_agentTestHelper->m_ioContext.run_for(500ms); - } - } - } - - void createClient(const ConfigOptions &options, unique_ptr &&handler) - { - ConfigOptions opts(options); - MergeOptions(opts, {{MqttHost, "127.0.0.1"s}, - {MqttPort, m_port}, - {MqttTls, false}, - {AutoAvailable, false}, - {RealTime, false}}); - m_client = make_shared(m_agentTestHelper->m_ioContext, - opts, std::move(handler)); - } - - bool startClient() - { - bool started = m_client && m_client->start(); - if (started) - { - return waitFor(5s, [this]() { return m_client->isConnected(); }); - } - return started; - } - - void addAdapter(ConfigOptions options = ConfigOptions {}) - { - m_agentTestHelper->addAdapter(options, "localhost", 0, - m_agentTestHelper->m_agent->getDefaultDevice()->getName()); - } - - std::unique_ptr m_jsonPrinter; - std::shared_ptr m_server; - std::shared_ptr m_client; - std::shared_ptr m_service; - std::unique_ptr m_agentTestHelper; - uint16_t m_port {0}; -}; - -TEST_F(MqttSinkTest, mqtt_sink_should_be_loaded_by_agent) -{ - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - - ASSERT_TRUE(service); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker) -{ - ConfigOptions options; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_with_UserNameandPassword) -{ - ConfigOptions options {{MqttUserName, "MQTT-SINK"s}, {MqttPassword, "mtconnect"s}}; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent("", options); - auto service = m_agentTestHelper->getMqttLegacyService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_connect_to_broker_without_UserNameandPassword) -{ - ConfigOptions options; - createServer(options); - startServer(); - - ASSERT_NE(0, m_port); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_device) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotDevice = false; - handler->m_receive = [&gotDevice, &parser](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Device/000", topic); - - ErrorList list; - auto ptr = parser.parse(device_model::Device::getRoot(), payload, "2.0", list); - EXPECT_EQ(0, list.size()); - auto dev = dynamic_pointer_cast(ptr); - EXPECT_TRUE(dev); - EXPECT_EQ("LinuxCNC", dev->getComponentName()); - EXPECT_EQ("000", *dev->getUuid()); - - gotDevice = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - m_client->subscribe("MTConnect/Device/000"); - - createAgent(); - - auto service = m_agentTestHelper->getMqttLegacyService(); - - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - - ASSERT_TRUE(waitFor(5s, [&gotDevice]() { return gotDevice; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Streams) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool foundLineDataItem = false; - handler->m_receive = [&foundLineDataItem](std::shared_ptr client, - const std::string &topic, const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]", topic); - - auto jdoc = json::parse(payload); - string value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ("204", value); - foundLineDataItem = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - - m_client->subscribe("MTConnect/Observation/000/Controller[Controller]/Path/Events/Line[line]"); - m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); - - ASSERT_TRUE(waitFor(5s, [&foundLineDataItem]() { return foundLineDataItem; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Asset) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Asset/0001", topic); - auto jdoc = json::parse(payload); - string id = jdoc.at("/Part/assetId"_json_pointer).get(); - EXPECT_EQ("0001", id); - gotControllerDataItem = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Asset/0001"); - - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|@ASSET@|@1|Part|TEST 1"); - - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_RotaryMode) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotRotaryMode = false; - handler->m_receive = [&gotRotaryMode](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]", - topic); - auto jdoc = json::parse(payload); - - double v = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(5000.0, v); - gotRotaryMode = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Samples/SpindleSpeed.Actual[Sspeed]"); - - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|block|G01X00|Sspeed|5000|line|204"); - - ASSERT_TRUE(waitFor(5s, [&gotRotaryMode]() { return gotRotaryMode; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Dataset) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]", - topic); - auto jdoc = json::parse(payload); - auto id = jdoc.at("/value/a"_json_pointer).get(); - EXPECT_EQ(1, id); - gotControllerDataItem = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent("/samples/data_set.xml"); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/VariableDataSet[vars]"); - - m_agentTestHelper->m_adapter->processData("TIME|vars|a=1 b=2 c=3"); - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Table) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotControllerDataItem = false; - handler->m_receive = [&gotControllerDataItem](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/WorkOffsetTable[wpo]", - topic); - auto jdoc = json::parse(payload); - - auto jValue = jdoc.at("/value"_json_pointer); - int count = 0; - if (jValue.is_object()) - { - for (auto &[key, value] : jValue.items()) - { - if (key == "G53.1" || key == "G53.2" || key == "G53.3") - { - for (auto &[subKey, subValue] : value.items()) - { - if (key == "G53.1" && ((subKey == "X" && subValue.get() == 1) || - (subKey == "Y" && subValue.get() == 2) || - (subKey == "Z" && subValue.get() == 3))) - { - count++; - } - else if (key == "G53.2" && ((subKey == "X" && subValue.get() == 4) || - (subKey == "Y" && subValue.get() == 5) || - (subKey == "Z" && subValue.get() == 6))) - { - count++; - } - else if (key == "G53.3" && ((subKey == "X" && subValue.get() == 7.0) || - (subKey == "Y" && subValue.get() == 8.0) || - (subKey == "Z" && subValue.get() == 9.0) || - (subKey == "U" && subValue.get() == 10.0))) - { - count++; - } - } - } - } - EXPECT_EQ(10, count); - gotControllerDataItem = true; - } - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent("/samples/data_set.xml"); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Controller[Controller]/Path[path]/Events/" - "WorkOffsetTable[wpo]"); - - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|wpo|G53.1={X=1.0 Y=2.0 Z=3.0} G53.2={X=4.0 Y=5.0 Z=6.0}" - "G53.3={X=7.0 Y=8.0 Z=9 U=10.0}"); - - ASSERT_TRUE(waitFor(5s, [&gotControllerDataItem]() { return gotControllerDataItem; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_Temperature) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotTemperature = false; - handler->m_receive = [&gotTemperature](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" - "Temperature[z_motor_temp]", - topic); - auto jdoc = json::parse(payload); - - auto value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(81.0, value); - gotTemperature = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Linear[Z]/Motor[motor_name]/Samples/" - "Temperature[z_motor_temp]"); - - m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|z_motor_temp|81"); - - ASSERT_TRUE(waitFor(5s, [&gotTemperature]() { return gotTemperature; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_LinearLoad) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotLinearLoad = false; - handler->m_receive = [&gotLinearLoad](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]", topic); - auto jdoc = json::parse(payload); - auto value = jdoc.at("/value"_json_pointer).get(); - EXPECT_EQ(50.0, value); - gotLinearLoad = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/Load[Xload]"); - - m_agentTestHelper->m_adapter->processData("2018-04-27T05:00:26.555666|Xload|50"); - ASSERT_TRUE(waitFor(5s, [&gotLinearLoad]() { return gotLinearLoad; })); -} - -TEST_F(MqttSinkTest, mqtt_sink_should_publish_DynamicCalibration) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - - entity::JsonParser parser; - - auto handler = make_unique(); - bool gotCalibration = false; - handler->m_receive = [this, &gotCalibration](std::shared_ptr, - const std::string &topic, - const std::string &payload) { - EXPECT_EQ( - "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]", - topic); - auto jdoc = json::parse(payload); - - auto value = jdoc.at("/value"_json_pointer); - ASSERT_TRUE(value.is_array()); - EXPECT_EQ(25, value.size()); - gotCalibration = true; - }; - - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - - createAgent(); - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - - m_client->subscribe( - "MTConnect/Observation/000/Axes[Axes]/Linear[X]/Samples/PositionTimeSeries.Actual[Xts]"); - - m_agentTestHelper->m_adapter->processData( - "2021-02-01T12:00:00Z|Xts|25|| 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 5118 " - "5119 5119 5118 " - "5118 5117 5117 5119 5119 5118 5118 5118 5118 5118"); - - ASSERT_TRUE(waitFor(5s, [&gotCalibration]() { return gotCalibration; })); -} - -/// @test check if the condition includes the state as the key -TEST_F(MqttSinkTest, mqtt_should_publish_conditions_with_the_state_as_the_key) -{ - ConfigOptions options; - createServer(options); - startServer(); - ASSERT_NE(0, m_port); - entity::JsonParser parser; - auto handler = make_unique(); - bool gotCondition = false; - - handler->m_receive = [&gotCondition](std::shared_ptr, const std::string &topic, - const std::string &payload) { - EXPECT_EQ("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature", topic); - auto jdoc = json::parse(payload); - EXPECT_EQ("Temperature is too high", jdoc.at("/Fault/value"_json_pointer).get()); - EXPECT_EQ("X111", jdoc.at("/Fault/nativeCode"_json_pointer).get()); - EXPECT_EQ("BAD", jdoc.at("/Fault/nativeSeverity"_json_pointer).get()); - EXPECT_EQ("HIGH", jdoc.at("/Fault/qualifier"_json_pointer).get()); - EXPECT_EQ("TEMPERATURE", jdoc.at("/Fault/type"_json_pointer).get()); - - gotCondition = true; - }; - createClient(options, std::move(handler)); - ASSERT_TRUE(startClient()); - createAgent(); - - auto di = m_agentTestHelper->m_agent->getDataItemById("ctmp"); - ASSERT_TRUE(di); - ASSERT_EQ("000/Axes[Axes]/Rotary[C]/Condition/Temperature", di->getTopic()); - - auto service = m_agentTestHelper->getMqttLegacyService(); - ASSERT_TRUE(waitFor(5s, [&service]() { return service->isConnected(); })); - m_client->subscribe("MTConnect/Observation/000/Axes[Axes]/Rotary[C]/Condition/Temperature"); - - m_agentTestHelper->m_adapter->processData( - "2018-04-27T05:00:26.555666|ctmp|fault|X111|BAD|HIGH|Temperature is too high"); - ASSERT_TRUE(waitFor(5s, [&gotCondition]() { return gotCondition; })); -} diff --git a/test_package/mqtt_sink_test.cpp b/test_package/mqtt_sink_test.cpp index 1d5eb23ce..1be606806 100644 --- a/test_package/mqtt_sink_test.cpp +++ b/test_package/mqtt_sink_test.cpp @@ -50,7 +50,7 @@ int main(int argc, char *argv[]) using json = nlohmann::json; -class MqttSink2Test : public testing::Test +class MqttSinkTest : public testing::Test { protected: void SetUp() override @@ -62,6 +62,7 @@ class MqttSink2Test : public testing::Test void TearDown() override { const auto agent = m_agentTestHelper->getAgent(); + m_agentTestHelper->m_ioContext.run_for(500ms); if (agent) { m_agentTestHelper->getAgent()->stop(); @@ -186,7 +187,7 @@ class MqttSink2Test : public testing::Test uint16_t m_port {0}; }; -TEST_F(MqttSink2Test, mqtt_sink_flat_formatt_check) +TEST_F(MqttSinkTest, mqtt_sink_flat_formatt_check) { ConfigOptions options {{MqttMaxTopicDepth, 9}, {ProbeTopic, "Device/F/l/a/t/F/o/r/m/a/t"s}}; createServer(options); @@ -200,7 +201,7 @@ TEST_F(MqttSink2Test, mqtt_sink_flat_formatt_check) ASSERT_TRUE(waitFor(10s, [&service]() { return service->isConnected(); })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe) { ConfigOptions options; createServer(options); @@ -239,7 +240,7 @@ TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe) ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Sample) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) { ConfigOptions options; createServer(options); @@ -276,7 +277,7 @@ TEST_F(MqttSink2Test, mqtt_sink_should_publish_Sample) ASSERT_TRUE(waitFor(10s, [&gotSample]() { return gotSample; })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Current) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Current) { ConfigOptions options; createServer(options); @@ -313,7 +314,7 @@ TEST_F(MqttSink2Test, mqtt_sink_should_publish_Current) ASSERT_TRUE(waitFor(1s, [&gotCurrent]() { return gotCurrent; })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_with_uuid_first) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe_with_uuid_first) { ConfigOptions options; createServer(options); @@ -352,7 +353,7 @@ TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_with_uuid_first) ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_no_device_in_format) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_Probe_no_device_in_format) { ConfigOptions options; createServer(options); @@ -391,7 +392,7 @@ TEST_F(MqttSink2Test, mqtt_sink_should_publish_Probe_no_device_in_format) ASSERT_TRUE(waitFor(1s, [&gotDevice]() { return gotDevice; })); } -TEST_F(MqttSink2Test, mqtt_sink_should_publish_agent_device) +TEST_F(MqttSinkTest, mqtt_sink_should_publish_agent_device) { ConfigOptions options; createServer(options); From e09d8d79c628a0e3ae405d1cf41f9117ad98aa64 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 13 May 2024 13:44:35 -0400 Subject: [PATCH 109/128] Merged in main branch to main-dev --- CMakeLists.txt | 2 +- src/mtconnect/mqtt/mqtt_client_impl.hpp | 1 + src/mtconnect/sink/mqtt_sink/mqtt_service.cpp | 22 ++++++++++--------- src/mtconnect/sink/mqtt_sink/mqtt_service.hpp | 2 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 3 ++- test_package/mqtt_sink_test.cpp | 15 +++++++++---- 6 files changed, 28 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ea263a17..9f23f2b32 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) set(AGENT_VERSION_BUILD 0) -set(AGENT_VERSION_RC "RC2") +set(AGENT_VERSION_RC "RC3") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index af71cf54c..7b7155e50 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -164,6 +164,7 @@ namespace mtconnect { m_connected = false; if (m_handler && m_handler->m_disconnected) m_handler->m_disconnected(shared_from_this()); + if (m_running) { disconnected(); diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp index 7c17edbfd..72fbfd6e4 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp @@ -187,7 +187,7 @@ namespace mtconnect { } } - auto seq = m_sinkContract->getCircularBuffer().getSequence(); + auto seq = publishCurrent(boost::system::error_code {}); for (auto &dev : m_sinkContract->getDevices()) { FilterSet filterSet = filterForDevice(dev); @@ -199,10 +199,8 @@ namespace mtconnect { sampler->observe(seq, [this](const std::string &id) { return m_sinkContract->getDataItemById(id).get(); }); - sampler->handlerCompleted(); + publishSample(sampler); } - - publishCurrent(boost::system::error_code {}); } /// @brief publish sample when observations arrive. @@ -246,18 +244,20 @@ namespace mtconnect { return end; } - void MqttService::publishCurrent(boost::system::error_code ec) + SequenceNumber_t MqttService::publishCurrent(boost::system::error_code ec) { + SequenceNumber_t firstSeq, seq = 0; + if (ec) { LOG(warning) << "Mqtt2Service::publishCurrent: " << ec.message(); - return; + return 0; } if (!m_client->isRunning() || !m_client->isConnected()) { LOG(warning) << "Mqtt2Service::publishCurrent: client stopped"; - return; + return 0; } for (auto &device : m_sinkContract->getDevices()) @@ -266,7 +266,6 @@ namespace mtconnect { LOG(debug) << "Publishing current for: " << topic; ObservationList observations; - SequenceNumber_t firstSeq, seq; auto filterSet = filterForDevice(device); { @@ -290,6 +289,8 @@ namespace mtconnect { m_currentTimer.expires_after(m_currentInterval); m_currentTimer.async_wait(boost::asio::bind_executor( m_strand, boost::bind(&MqttService::publishCurrent, this, _1))); + + return seq; } bool MqttService::publish(observation::ObservationPtr &observation) @@ -327,8 +328,9 @@ namespace mtconnect { LOG(debug) << "Publishing Asset to topic: " << topic; - auto doc = m_jsonPrinter->print(asset); - + asset::AssetList list {asset}; + auto doc = m_printer->printAssets( + m_instanceId, uint32_t(m_sinkContract->getAssetStorage()->getMaxAssets()), 1, list); stringstream buffer; buffer << doc; diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp index 6cba52409..7a6228152 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.hpp @@ -96,7 +96,7 @@ namespace mtconnect { void pubishInitialContent(); /// @brief Publish a current using `CurrentInterval` option. - void publishCurrent(boost::system::error_code ec); + SequenceNumber_t publishCurrent(boost::system::error_code ec); /// @brief publish sample when observations arrive. SequenceNumber_t publishSample(std::shared_ptr sampler); diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 914f8b3da..8e4a4366d 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -550,12 +550,13 @@ namespace mtconnect { auto format = request->parameter("format"); auto pretty = request->parameter("pretty").value_or(false); auto printer = m_sinkContract->getPrinter(acceptFormat(request->m_accepts, format)); - + list ids; stringstream str(*asset); string id; while (getline(str, id, ';')) ids.emplace_back(id); + respond(session, assetIdsRequest(printer, ids, pretty, request->m_requestId), request->m_requestId); } diff --git a/test_package/mqtt_sink_test.cpp b/test_package/mqtt_sink_test.cpp index 1be606806..8dfa43d0a 100644 --- a/test_package/mqtt_sink_test.cpp +++ b/test_package/mqtt_sink_test.cpp @@ -62,7 +62,6 @@ class MqttSinkTest : public testing::Test void TearDown() override { const auto agent = m_agentTestHelper->getAgent(); - m_agentTestHelper->m_ioContext.run_for(500ms); if (agent) { m_agentTestHelper->getAgent()->stop(); @@ -251,8 +250,15 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) auto handler = make_unique(); bool gotSample = false; - handler->m_receive = [&gotSample](std::shared_ptr client, const std::string &topic, + bool first = true; + handler->m_receive = [&gotSample, &first](std::shared_ptr client, const std::string &topic, const std::string &payload) { + if (first) + { + first = false; + } + else + { EXPECT_EQ("MTConnect/Sample/000", topic); auto jdoc = json::parse(payload); @@ -260,6 +266,7 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); gotSample = true; + } }; createClient(options, std::move(handler)); @@ -270,8 +277,8 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) auto service = m_agentTestHelper->getMqttService(); - ASSERT_TRUE(waitFor(60s, [&service]() { return service->isConnected(); })); - ASSERT_FALSE(gotSample); + ASSERT_TRUE(waitFor(60s, [&first]() { return !first; })); + ASSERT_FALSE(first); m_agentTestHelper->m_adapter->processData("2021-02-01T12:00:00Z|line|204"); ASSERT_TRUE(waitFor(10s, [&gotSample]() { return gotSample; })); From e54f680eb1bfc2f7da9c37915151043238f2c5d6 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 13 May 2024 13:46:13 -0400 Subject: [PATCH 110/128] Vesion 2.5.0.0 RC 4 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f23f2b32..589c2ab4c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) set(AGENT_VERSION_BUILD 0) -set(AGENT_VERSION_RC "RC3") +set(AGENT_VERSION_RC "RC4") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) From 182e9e468b7b2164e903a60cf3cec5eda96daa6d Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 15 May 2024 11:08:35 -0400 Subject: [PATCH 111/128] Changed conanfile to 2.5 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 8df4cd46f..0a4bfd368 100644 --- a/conanfile.py +++ b/conanfile.py @@ -9,7 +9,7 @@ class MTConnectAgentConan(ConanFile): name = "mtconnect_agent" - version = "2.3" + version = "2.5" url = "https://github.com/mtconnect/cppagent.git" license = "Apache License 2.0" settings = "os", "compiler", "arch", "build_type" From 52bf9ec9665dcfcbb59c3861403d5c7f5b70ebc2 Mon Sep 17 00:00:00 2001 From: Trais McAllister Date: Sun, 22 Sep 2024 01:01:50 -0400 Subject: [PATCH 112/128] Transpiled observation_validations.hpp --- .../validation/observation_validations.hpp | 337 +++++++----------- 1 file changed, 138 insertions(+), 199 deletions(-) diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index 1f7cb73ef..967220520 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,200 +1,139 @@ Validation ControlledVocabularies { - {"ActiveAxes", {}}, - {"ActuatorState", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"Alarm", {}}, - {"AssetChanged", {}}, - {"AssetRemoved", {}}, - {"Availability", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, - {"AxisCoupling", {{"TANDEM", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}, {"SLAVE", 0}}}, - {"AxisFeedrateOverride", {}}, - {"AxisInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"AxisState", {{"HOME", 0}, {"TRAVEL", 0}, {"PARKED", 0}, {"STOPPED", 0}}}, - {"Block", {}}, - {"BlockCount", {}}, - {"ChuckInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"ChuckState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, - {"Code", {}}, - {"CompositionState", {}}, - {"ControllerMode", - {{"AUTOMATIC", 0}, - {"MANUAL", 0}, - {"MANUAL_DATA_INPUT", 0}, - {"SEMI_AUTOMATIC", 0}, - {"EDIT", 0}, - {"FEED_HOLD", SCHEMA_VERSION(1, 3)}}}, - {"ControllerModeOverride", {{"ON", 0}, {"OFF", 0}}}, - {"CoupledAxes", {}}, - {"DateCode", {}}, - {"DeviceUuid", {}}, - {"Direction", - {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, - {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, - {"POSITIVE", SCHEMA_VERSION(1, 4)}, - {"NEGATIVE", SCHEMA_VERSION(1, 4)}}}, - {"DoorState", {{"OPEN", 0}, {"CLOSED", 0}, {"UNLATCHED", 0}}}, - {"EmergencyStop", {{"ARMED", 0}, {"TRIGGERED", 0}}}, - {"EndOfBar", {{"YES", 0}, {"NO", 0}}}, - {"EquipmentMode", {{"ON", 0}, {"OFF", 0}}}, - {"Execution", - {{"READY", 0}, - {"ACTIVE", 0}, - {"INTERRUPTED", 0}, - {"FEED_HOLD", 0}, - {"STOPPED", 0}, - {"OPTIONAL_STOP", 0}, - {"PROGRAM_STOPPED", 0}, - {"PROGRAM_COMPLETED", 0}, - {"WAIT", 0}, - {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}}}, - {"FunctionalMode", - {{"PRODUCTION", 0}, - {"SETUP", 0}, - {"TEARDOWN", 0}, - {"MAINTENANCE", 0}, - {"PROCESS_DEVELOPMENT", 0}}}, - {"Hardness", {}}, - {"Line", {}}, - {"LineLabel", {}}, - {"LineNumber", {}}, - {"Material", {}}, - {"MaterialLayer", {}}, - {"Message", {}}, - {"OperatorId", {}}, - {"PalletId", {}}, - {"PartCount", {}}, - {"PartDetect", {{"PRESENT", 0}, {"NOT_PRESENT", 0}}}, - {"PartId", {}}, - {"PartNumber", {}}, - {"PathFeedrateOverride", {}}, - {"PathMode", {{"INDEPENDENT", 0}, {"MASTER", 0}, {"SYNCHRONOUS", 0}, {"MIRROR", 0}}}, - {"PowerState", {{"ON", 0}, {"OFF", 0}}}, - {"PowerStatus", {{"ON", SCHEMA_VERSION(1, 1)}, {"OFF", SCHEMA_VERSION(1, 1)}}}, - {"ProcessTime", {}}, - {"Program", {}}, - {"ProgramComment", {}}, - {"ProgramEdit", {{"ACTIVE", 0}, {"READY", 0}, {"NOT_READY", 0}}}, - {"ProgramEditName", {}}, - {"ProgramHeader", {}}, - {"ProgramLocation", {}}, - {"ProgramLocationType", {{"LOCAL", 0}, {"EXTERNAL", 0}}}, - {"ProgramNestLevel", {}}, - {"RotaryMode", {{"SPINDLE", 0}, {"INDEX", 0}, {"CONTOUR", 0}}}, - {"RotaryVelocityOverride", {}}, - {"SerialNumber", {}}, - {"SpindleInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, - {"ToolAssetId", {}}, - {"ToolGroup", {}}, - {"ToolId", {}}, - {"ToolNumber", {}}, - {"ToolOffset", {}}, - {"User", {}}, - {"Variable", {}}, - {"WaitState", - {{"POWERING_UP", 0}, - {"POWERING_DOWN", 0}, - {"PART_LOAD", 0}, - {"PART_UNLOAD", 0}, - {"TOOL_LOAD", 0}, - {"TOOL_UNLOAD", 0}, - {"MATERIAL_LOAD", 0}, - {"MATERIAL_UNLOAD", 0}, - {"SECONDARY_PROCESS", 0}, - {"PAUSING", 0}, - {"RESUMING", 0}}}, - {"Wire", {}}, - {"WorkholdingId", {}}, - {"WorkOffset", {}}, - {"OperatingSystem", {}}, - {"Firmware", {}}, - {"Application", {}}, - {"Library", {}}, - {"Hardware", {}}, - {"Network", {}}, - {"Rotation", {}}, - {"Translation", {}}, - {"ProcessKindId", {}}, - {"PartStatus", {{"PASS", 0}, {"FAIL", 0}}}, - {"AlarmLimit", {}}, - {"ProcessAggregateId", {}}, - {"PartKindId", {}}, - {"AdapterURI", {}}, - {"DeviceRemoved", {}}, - {"DeviceChanged", {}}, - {"SpecificationLimit", {}}, - {"ConnectionStatus", {{"CLOSED", 0}, {"LISTEN", 0}, {"ESTABLISHED", 0}}}, - {"AdapterSoftwareVersion", {}}, - {"SensorAttachment", {}}, - {"ControlLimit", {}}, - {"DeviceAdded", {}}, - {"MTConnectVersion", {}}, - {"ProcessOccurrenceId", {}}, - {"PartGroupId", {}}, - {"PartUniqueId", {}}, - {"ActivationCount", {}}, - {"DeactivationCount", {}}, - {"TransferCount", {}}, - {"LoadCount", {}}, - {"PartProcessingState", - {{"NEEDS_PROCESSING", 0}, - {"IN_PROCESS", 0}, - {"PROCESSING_ENDED", 0}, - {"PROCESSING_ENDED_COMPLETE", 0}, - {"PROCESSING_ENDED_STOPPED", 0}, - {"PROCESSING_ENDED_ABORTED", 0}, - {"PROCESSING_ENDED_LOST", 0}, - {"PROCESSING_ENDED_SKIPPED", 0}, - {"PROCESSING_ENDED_REJECTED", 0}, - {"WAITING_FOR_TRANSIT", 0}, - {"IN_TRANSIT", 0}, - {"TRANSIT_COMPLETE", 0}}}, - {"ProcessState", - {{"INITIALIZING", 0}, - {"READY", 0}, - {"ACTIVE", 0}, - {"COMPLETE", 0}, - {"INTERRUPTED", 0}, - {"ABORTED", 0}}}, - {"ValveState", {{"OPEN", 0}, {"OPENING", 0}, {"CLOSED", 0}, {"CLOSING", 0}}}, - {"LockState", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, - {"UnloadCount", {}}, - {"CycleCount", {}}, - {"OperatingMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, - {"AssetCount", {}}, - {"MaintenanceList", {}}, - {"FixtureId", {}}, - {"PartCountType", {{"EACH", 0}, {"BATCH", 0}}}, - {"ClockTime", {}}, - {"NetworkPort", {}}, - {"HostName", {}}, - {"LeakDetect", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, - {"BatteryState", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGING", 0}, {"DISCHARGED", 0}}}, - {"FeaturePersisitentId", {}}, - {"SensorState", {}}, - {"ComponentData", {}}, - {"WorkOffsets", {}}, - {"ToolOffsets", {}}, - {"FeatureMeasurement", {}}, - {"CharacteristicPersistentId", {}}, - {"MeasurementType", {}}, - {"MeasurementValue", {}}, - {"MeasurementUnits", {}}, - {"CharacteristicStatus", - {{"PASS", 0}, - {"FAIL", 0}, - {"REWORK", 0}, - {"SYSTEM_ERROR", 0}, - {"INDETERMINATE", 0}, - {"NOT_ANALYZED", 0}, - {"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, - {"UNDEFINED", 0}}}, - {"UncertaintyType", {{"COMBINED", 0}, {"MEAN", 0}}}, - {"Uncertainty", {}}, - {"AlarmLimits", {}}, - {"ControlLimits", {}}, - {"SpecificationLimits", {}}, - {"ToolCuttingItem", {}}, - {"LocationAddress", {}}, - {"ActivePowerSource", {}}, - {"LocationNarrative", {}}, - {"Thickness", {}}, - {"LocationSpatialGeographic", {}}}; + {"ActiveAxes",{}}, + {"ActuatorState",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, + {"Alarm",{}}, + {"AssetChanged",{}}, + {"AssetRemoved",{}}, + {"Availability",{{"AVAILABLE", 0}, {"UNAVAILABLE", 0} }}, + {"AxisCoupling",{{"MASTER", 0}, {"SLAVE", 0}, {"SYNCHRONOUS", 0}, {"TANDEM", 0} }}, + {"AxisFeedrateOverride",{}}, + {"AxisInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, + {"AxisState",{{"HOME", 0}, {"PARKED", 0}, {"STOPPED", 0}, {"TRAVEL", 0} }}, + {"Block",{}}, + {"BlockCount",{}}, + {"ChuckInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, + {"ChuckState",{{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0} }}, + {"Code",{}}, + {"CompositionState",{}}, + {"ControllerMode",{{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}, {"EDIT", 0} }}, + {"ControllerModeOverride",{{"OFF", 0}, {"ON", 0} }}, + {"CoupledAxes",{}}, + {"DateCode",{}}, + {"DeviceUuid",{}}, + {"Direction",{{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)} }}, + {"DoorState",{{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0} }}, + {"EmergencyStop",{{"ARMED", 0}, {"TRIGGERED", 0} }}, + {"EndOfBar",{{"NO", 0}, {"YES", 0} }}, + {"EquipmentMode",{{"OFF", 0}, {"ON", 0} }}, + {"Execution",{{"ACTIVE", 0}, {"INTERRUPTED", 0}, {"READY", 0}, {"STOPPED", 0}, {"FEED_HOLD", 0}, {"PROGRAM_COMPLETED", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}, {"PROGRAM_STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"WAIT", 0} }}, + {"FunctionalMode",{{"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}, {"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0} }}, + {"Hardness",{}}, + {"Line",{}}, + {"LineLabel",{}}, + {"LineNumber",{}}, + {"Material",{}}, + {"MaterialLayer",{}}, + {"Message",{}}, + {"OperatorId",{}}, + {"PalletId",{}}, + {"PartCount",{}}, + {"PartDetect",{{"NOT_PRESENT", 0}, {"PRESENT", 0} }}, + {"PartId",{}}, + {"PartNumber",{}}, + {"PathFeedrateOverride",{}}, + {"PathMode",{{"INDEPENDENT", 0}, {"MIRROR", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0} }}, + {"PowerState",{{"OFF", 0}, {"ON", 0} }}, + {"PowerStatus",{{"OFF", SCHEMA_VERSION(1, 1)}, {"ON", SCHEMA_VERSION(1, 1)} }}, + {"ProcessTime",{}}, + {"Program",{}}, + {"ProgramComment",{}}, + {"ProgramEdit",{{"ACTIVE", 0}, {"NOT_READY", 0}, {"READY", 0} }}, + {"ProgramEditName",{}}, + {"ProgramHeader",{}}, + {"ProgramLocation",{}}, + {"ProgramLocationType",{{"EXTERNAL", 0}, {"LOCAL", 0} }}, + {"ProgramNestLevel",{}}, + {"RotaryMode",{{"CONTOUR", 0}, {"INDEX", 0}, {"SPINDLE", 0} }}, + {"RotaryVelocityOverride",{}}, + {"SerialNumber",{}}, + {"SpindleInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, + {"ToolAssetId",{}}, + {"ToolGroup",{}}, + {"ToolId",{}}, + {"ToolNumber",{}}, + {"ToolOffset",{}}, + {"User",{}}, + {"Variable",{}}, + {"WaitState",{{"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"PAUSING", 0}, {"POWERING_DOWN", 0}, {"POWERING_UP", 0}, {"RESUMING", 0}, {"SECONDARY_PROCESS", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0} }}, + {"Wire",{}}, + {"WorkholdingId",{}}, + {"WorkOffset",{}}, + {"OperatingSystem",{}}, + {"Firmware",{}}, + {"Application",{}}, + {"Library",{}}, + {"Hardware",{}}, + {"Network",{}}, + {"Rotation",{}}, + {"Translation",{}}, + {"ProcessKindId",{}}, + {"PartStatus",{{"FAIL", 0}, {"PASS", 0} }}, + {"AlarmLimit",{}}, + {"ProcessAggregateId",{}}, + {"PartKindId",{}}, + {"AdapterURI",{}}, + {"DeviceRemoved",{}}, + {"DeviceChanged",{}}, + {"SpecificationLimit",{}}, + {"ConnectionStatus",{{"CLOSED", 0}, {"ESTABLISHED", 0}, {"LISTEN", 0} }}, + {"AdapterSoftwareVersion",{}}, + {"SensorAttachment",{}}, + {"ControlLimit",{}}, + {"DeviceAdded",{}}, + {"MTConnectVersion",{}}, + {"ProcessOccurrenceId",{}}, + {"PartGroupId",{}}, + {"PartUniqueId",{}}, + {"ActivationCount",{}}, + {"DeactivationCount",{}}, + {"TransferCount",{}}, + {"LoadCount",{}}, + {"PartProcessingState",{{"IN_PROCESS", 0}, {"IN_TRANSIT", 0}, {"NEEDS_PROCESSING", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"TRANSIT_COMPLETE", 0}, {"WAITING_FOR_TRANSIT", 0} }}, + {"ProcessState",{{"ABORTED", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INITIALIZING", 0}, {"INTERRUPTED", 0}, {"READY", 0} }}, + {"ValveState",{{"CLOSED", 0}, {"CLOSING", 0}, {"OPEN", 0}, {"OPENING", 0} }}, + {"LockState",{{"LOCKED", 0}, {"UNLOCKED", 0} }}, + {"UnloadCount",{}}, + {"CycleCount",{}}, + {"OperatingMode",{{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0} }}, + {"AssetCount",{}}, + {"MaintenanceList",{}}, + {"FixtureId",{}}, + {"PartCountType",{{"BATCH", 0}, {"EACH", 0} }}, + {"ClockTime",{}}, + {"NetworkPort",{}}, + {"HostName",{}}, + {"LeakDetect",{{"DETECTED", 0}, {"NOT_DETECTED", 0} }}, + {"BatteryState",{{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGED", 0}, {"DISCHARGING", 0} }}, + {"FeaturePersisitentId",{}}, + {"SensorState",{}}, + {"ComponentData",{}}, + {"WorkOffsets",{}}, + {"ToolOffsets",{}}, + {"FeatureMeasurement",{}}, + {"CharacteristicPersistentId",{}}, + {"MeasurementType",{}}, + {"MeasurementValue",{}}, + {"MeasurementUnits",{}}, + {"CharacteristicStatus",{{"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"FAIL", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"PASS", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"UNDEFINED", 0} }}, + {"UncertaintyType",{{"COMBINED", 0}, {"MEAN", 0} }}, + {"Uncertainty",{}}, + {"AlarmLimits",{}}, + {"ControlLimits",{}}, + {"SpecificationLimits",{}}, + {"ToolCuttingItem",{}}, + {"LocationAddress",{}}, + {"ActivePowerSource",{}}, + {"LocationNarrative",{}}, + {"Thickness",{}}, + {"LocationSpatialGeographic",{}} +}; \ No newline at end of file From a650425ae9597d9c74711d7bffa2aebd2c2c8350 Mon Sep 17 00:00:00 2001 From: Trais McAllister Date: Sun, 22 Sep 2024 01:05:38 -0400 Subject: [PATCH 113/128] Update observation_validations.hpp --- .../validation/observation_validations.hpp | 274 +++++++++--------- 1 file changed, 137 insertions(+), 137 deletions(-) diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index 967220520..bc2843f23 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,139 +1,139 @@ Validation ControlledVocabularies { - {"ActiveAxes",{}}, - {"ActuatorState",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, - {"Alarm",{}}, - {"AssetChanged",{}}, - {"AssetRemoved",{}}, - {"Availability",{{"AVAILABLE", 0}, {"UNAVAILABLE", 0} }}, - {"AxisCoupling",{{"MASTER", 0}, {"SLAVE", 0}, {"SYNCHRONOUS", 0}, {"TANDEM", 0} }}, - {"AxisFeedrateOverride",{}}, - {"AxisInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, - {"AxisState",{{"HOME", 0}, {"PARKED", 0}, {"STOPPED", 0}, {"TRAVEL", 0} }}, - {"Block",{}}, - {"BlockCount",{}}, - {"ChuckInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, - {"ChuckState",{{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0} }}, - {"Code",{}}, - {"CompositionState",{}}, - {"ControllerMode",{{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}, {"EDIT", 0} }}, - {"ControllerModeOverride",{{"OFF", 0}, {"ON", 0} }}, - {"CoupledAxes",{}}, - {"DateCode",{}}, - {"DeviceUuid",{}}, - {"Direction",{{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)} }}, - {"DoorState",{{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0} }}, - {"EmergencyStop",{{"ARMED", 0}, {"TRIGGERED", 0} }}, - {"EndOfBar",{{"NO", 0}, {"YES", 0} }}, - {"EquipmentMode",{{"OFF", 0}, {"ON", 0} }}, - {"Execution",{{"ACTIVE", 0}, {"INTERRUPTED", 0}, {"READY", 0}, {"STOPPED", 0}, {"FEED_HOLD", 0}, {"PROGRAM_COMPLETED", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}, {"PROGRAM_STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"WAIT", 0} }}, - {"FunctionalMode",{{"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}, {"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0} }}, - {"Hardness",{}}, - {"Line",{}}, - {"LineLabel",{}}, - {"LineNumber",{}}, - {"Material",{}}, - {"MaterialLayer",{}}, - {"Message",{}}, - {"OperatorId",{}}, - {"PalletId",{}}, - {"PartCount",{}}, - {"PartDetect",{{"NOT_PRESENT", 0}, {"PRESENT", 0} }}, - {"PartId",{}}, - {"PartNumber",{}}, - {"PathFeedrateOverride",{}}, - {"PathMode",{{"INDEPENDENT", 0}, {"MIRROR", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0} }}, - {"PowerState",{{"OFF", 0}, {"ON", 0} }}, - {"PowerStatus",{{"OFF", SCHEMA_VERSION(1, 1)}, {"ON", SCHEMA_VERSION(1, 1)} }}, - {"ProcessTime",{}}, - {"Program",{}}, - {"ProgramComment",{}}, - {"ProgramEdit",{{"ACTIVE", 0}, {"NOT_READY", 0}, {"READY", 0} }}, - {"ProgramEditName",{}}, - {"ProgramHeader",{}}, - {"ProgramLocation",{}}, - {"ProgramLocationType",{{"EXTERNAL", 0}, {"LOCAL", 0} }}, - {"ProgramNestLevel",{}}, - {"RotaryMode",{{"CONTOUR", 0}, {"INDEX", 0}, {"SPINDLE", 0} }}, - {"RotaryVelocityOverride",{}}, - {"SerialNumber",{}}, - {"SpindleInterlock",{{"ACTIVE", 0}, {"INACTIVE", 0} }}, - {"ToolAssetId",{}}, - {"ToolGroup",{}}, - {"ToolId",{}}, - {"ToolNumber",{}}, - {"ToolOffset",{}}, - {"User",{}}, - {"Variable",{}}, - {"WaitState",{{"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"PAUSING", 0}, {"POWERING_DOWN", 0}, {"POWERING_UP", 0}, {"RESUMING", 0}, {"SECONDARY_PROCESS", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0} }}, - {"Wire",{}}, - {"WorkholdingId",{}}, - {"WorkOffset",{}}, - {"OperatingSystem",{}}, - {"Firmware",{}}, - {"Application",{}}, - {"Library",{}}, - {"Hardware",{}}, - {"Network",{}}, - {"Rotation",{}}, - {"Translation",{}}, - {"ProcessKindId",{}}, - {"PartStatus",{{"FAIL", 0}, {"PASS", 0} }}, - {"AlarmLimit",{}}, - {"ProcessAggregateId",{}}, - {"PartKindId",{}}, - {"AdapterURI",{}}, - {"DeviceRemoved",{}}, - {"DeviceChanged",{}}, - {"SpecificationLimit",{}}, - {"ConnectionStatus",{{"CLOSED", 0}, {"ESTABLISHED", 0}, {"LISTEN", 0} }}, - {"AdapterSoftwareVersion",{}}, - {"SensorAttachment",{}}, - {"ControlLimit",{}}, - {"DeviceAdded",{}}, - {"MTConnectVersion",{}}, - {"ProcessOccurrenceId",{}}, - {"PartGroupId",{}}, - {"PartUniqueId",{}}, - {"ActivationCount",{}}, - {"DeactivationCount",{}}, - {"TransferCount",{}}, - {"LoadCount",{}}, - {"PartProcessingState",{{"IN_PROCESS", 0}, {"IN_TRANSIT", 0}, {"NEEDS_PROCESSING", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"TRANSIT_COMPLETE", 0}, {"WAITING_FOR_TRANSIT", 0} }}, - {"ProcessState",{{"ABORTED", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INITIALIZING", 0}, {"INTERRUPTED", 0}, {"READY", 0} }}, - {"ValveState",{{"CLOSED", 0}, {"CLOSING", 0}, {"OPEN", 0}, {"OPENING", 0} }}, - {"LockState",{{"LOCKED", 0}, {"UNLOCKED", 0} }}, - {"UnloadCount",{}}, - {"CycleCount",{}}, - {"OperatingMode",{{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0} }}, - {"AssetCount",{}}, - {"MaintenanceList",{}}, - {"FixtureId",{}}, - {"PartCountType",{{"BATCH", 0}, {"EACH", 0} }}, - {"ClockTime",{}}, - {"NetworkPort",{}}, - {"HostName",{}}, - {"LeakDetect",{{"DETECTED", 0}, {"NOT_DETECTED", 0} }}, - {"BatteryState",{{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGED", 0}, {"DISCHARGING", 0} }}, - {"FeaturePersisitentId",{}}, - {"SensorState",{}}, - {"ComponentData",{}}, - {"WorkOffsets",{}}, - {"ToolOffsets",{}}, - {"FeatureMeasurement",{}}, - {"CharacteristicPersistentId",{}}, - {"MeasurementType",{}}, - {"MeasurementValue",{}}, - {"MeasurementUnits",{}}, - {"CharacteristicStatus",{{"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"FAIL", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"PASS", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"UNDEFINED", 0} }}, - {"UncertaintyType",{{"COMBINED", 0}, {"MEAN", 0} }}, - {"Uncertainty",{}}, - {"AlarmLimits",{}}, - {"ControlLimits",{}}, - {"SpecificationLimits",{}}, - {"ToolCuttingItem",{}}, - {"LocationAddress",{}}, - {"ActivePowerSource",{}}, - {"LocationNarrative",{}}, - {"Thickness",{}}, - {"LocationSpatialGeographic",{}} + {"ActiveAxes", {}}, + {"ActuatorState", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"Alarm", {}}, + {"AssetChanged", {}}, + {"AssetRemoved", {}}, + {"Availability", {{"AVAILABLE", 0}, {"UNAVAILABLE", 0}}}, + {"AxisCoupling", {{"MASTER", 0}, {"SLAVE", 0}, {"SYNCHRONOUS", 0}, {"TANDEM", 0}}}, + {"AxisFeedrateOverride", {}}, + {"AxisInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"AxisState", {{"HOME", 0}, {"PARKED", 0}, {"STOPPED", 0}, {"TRAVEL", 0}}}, + {"Block", {}}, + {"BlockCount", {}}, + {"ChuckInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ChuckState", {{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0}}}, + {"Code", {}}, + {"CompositionState", {}}, + {"ControllerMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"MANUAL_DATA_INPUT", 0}, {"SEMI_AUTOMATIC", 0}, {"FEED_HOLD", SCHEMA_VERSION(1, 3)}, {"EDIT", 0}}}, + {"ControllerModeOverride", {{"OFF", 0}, {"ON", 0}}}, + {"CoupledAxes", {}}, + {"DateCode", {}}, + {"DeviceUuid", {}}, + {"Direction", {{"CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"COUNTER_CLOCKWISE", SCHEMA_VERSION(1, 4)}, {"NEGATIVE", SCHEMA_VERSION(1, 4)}, {"POSITIVE", SCHEMA_VERSION(1, 4)}}}, + {"DoorState", {{"CLOSED", 0}, {"OPEN", 0}, {"UNLATCHED", 0}}}, + {"EmergencyStop", {{"ARMED", 0}, {"TRIGGERED", 0}}}, + {"EndOfBar", {{"NO", 0}, {"YES", 0}}}, + {"EquipmentMode", {{"OFF", 0}, {"ON", 0}}}, + {"Execution", {{"ACTIVE", 0}, {"INTERRUPTED", 0}, {"READY", 0}, {"STOPPED", 0}, {"FEED_HOLD", 0}, {"PROGRAM_COMPLETED", 0}, {"PROGRAM_OPTIONAL_STOP", SCHEMA_VERSION(1, 4)}, {"PROGRAM_STOPPED", 0}, {"OPTIONAL_STOP", 0}, {"WAIT", 0}}}, + {"FunctionalMode", {{"MAINTENANCE", 0}, {"PROCESS_DEVELOPMENT", 0}, {"PRODUCTION", 0}, {"SETUP", 0}, {"TEARDOWN", 0}}}, + {"Hardness", {}}, + {"Line", {}}, + {"LineLabel", {}}, + {"LineNumber", {}}, + {"Material", {}}, + {"MaterialLayer", {}}, + {"Message", {}}, + {"OperatorId", {}}, + {"PalletId", {}}, + {"PartCount", {}}, + {"PartDetect", {{"NOT_PRESENT", 0}, {"PRESENT", 0}}}, + {"PartId", {}}, + {"PartNumber", {}}, + {"PathFeedrateOverride", {}}, + {"PathMode", {{"INDEPENDENT", 0}, {"MIRROR", 0}, {"SYNCHRONOUS", 0}, {"MASTER", 0}}}, + {"PowerState", {{"OFF", 0}, {"ON", 0}}}, + {"PowerStatus", {{"OFF", SCHEMA_VERSION(1, 1)}, {"ON", SCHEMA_VERSION(1, 1)}}}, + {"ProcessTime", {}}, + {"Program", {}}, + {"ProgramComment", {}}, + {"ProgramEdit", {{"ACTIVE", 0}, {"NOT_READY", 0}, {"READY", 0}}}, + {"ProgramEditName", {}}, + {"ProgramHeader", {}}, + {"ProgramLocation", {}}, + {"ProgramLocationType", {{"EXTERNAL", 0}, {"LOCAL", 0}}}, + {"ProgramNestLevel", {}}, + {"RotaryMode", {{"CONTOUR", 0}, {"INDEX", 0}, {"SPINDLE", 0}}}, + {"RotaryVelocityOverride", {}}, + {"SerialNumber", {}}, + {"SpindleInterlock", {{"ACTIVE", 0}, {"INACTIVE", 0}}}, + {"ToolAssetId", {}}, + {"ToolGroup", {}}, + {"ToolId", {}}, + {"ToolNumber", {}}, + {"ToolOffset", {}}, + {"User", {}}, + {"Variable", {}}, + {"WaitState", {{"MATERIAL_LOAD", 0}, {"MATERIAL_UNLOAD", 0}, {"PART_LOAD", 0}, {"PART_UNLOAD", 0}, {"PAUSING", 0}, {"POWERING_DOWN", 0}, {"POWERING_UP", 0}, {"RESUMING", 0}, {"SECONDARY_PROCESS", 0}, {"TOOL_LOAD", 0}, {"TOOL_UNLOAD", 0}}}, + {"Wire", {}}, + {"WorkholdingId", {}}, + {"WorkOffset", {}}, + {"OperatingSystem", {}}, + {"Firmware", {}}, + {"Application", {}}, + {"Library", {}}, + {"Hardware", {}}, + {"Network", {}}, + {"Rotation", {}}, + {"Translation", {}}, + {"ProcessKindId", {}}, + {"PartStatus", {{"FAIL", 0}, {"PASS", 0}}}, + {"AlarmLimit", {}}, + {"ProcessAggregateId", {}}, + {"PartKindId", {}}, + {"AdapterURI", {}}, + {"DeviceRemoved", {}}, + {"DeviceChanged", {}}, + {"SpecificationLimit", {}}, + {"ConnectionStatus", {{"CLOSED", 0}, {"ESTABLISHED", 0}, {"LISTEN", 0}}}, + {"AdapterSoftwareVersion", {}}, + {"SensorAttachment", {}}, + {"ControlLimit", {}}, + {"DeviceAdded", {}}, + {"MTConnectVersion", {}}, + {"ProcessOccurrenceId", {}}, + {"PartGroupId", {}}, + {"PartUniqueId", {}}, + {"ActivationCount", {}}, + {"DeactivationCount", {}}, + {"TransferCount", {}}, + {"LoadCount", {}}, + {"PartProcessingState", {{"IN_PROCESS", 0}, {"IN_TRANSIT", 0}, {"NEEDS_PROCESSING", 0}, {"PROCESSING_ENDED", 0}, {"PROCESSING_ENDED_ABORTED", 0}, {"PROCESSING_ENDED_COMPLETE", 0}, {"PROCESSING_ENDED_LOST", 0}, {"PROCESSING_ENDED_REJECTED", 0}, {"PROCESSING_ENDED_SKIPPED", 0}, {"PROCESSING_ENDED_STOPPED", 0}, {"TRANSIT_COMPLETE", 0}, {"WAITING_FOR_TRANSIT", 0}}}, + {"ProcessState", {{"ABORTED", 0}, {"ACTIVE", 0}, {"COMPLETE", 0}, {"INITIALIZING", 0}, {"INTERRUPTED", 0}, {"READY", 0}}}, + {"ValveState", {{"CLOSED", 0}, {"CLOSING", 0}, {"OPEN", 0}, {"OPENING", 0}}}, + {"LockState", {{"LOCKED", 0}, {"UNLOCKED", 0}}}, + {"UnloadCount", {}}, + {"CycleCount", {}}, + {"OperatingMode", {{"AUTOMATIC", 0}, {"MANUAL", 0}, {"SEMI_AUTOMATIC", 0}}}, + {"AssetCount", {}}, + {"MaintenanceList", {}}, + {"FixtureId", {}}, + {"PartCountType", {{"BATCH", 0}, {"EACH", 0}}}, + {"ClockTime", {}}, + {"NetworkPort", {}}, + {"HostName", {}}, + {"LeakDetect", {{"DETECTED", 0}, {"NOT_DETECTED", 0}}}, + {"BatteryState", {{"CHARGED", 0}, {"CHARGING", 0}, {"DISCHARGED", 0}, {"DISCHARGING", 0}}}, + {"FeaturePersisitentId", {}}, + {"SensorState", {}}, + {"ComponentData", {}}, + {"WorkOffsets", {}}, + {"ToolOffsets", {}}, + {"FeatureMeasurement", {}}, + {"CharacteristicPersistentId", {}}, + {"MeasurementType", {}}, + {"MeasurementValue", {}}, + {"MeasurementUnits", {}}, + {"CharacteristicStatus", {{"BASIC_OR_THEORETIC_EXACT_DIMENSION", 0}, {"FAIL", 0}, {"INDETERMINATE", 0}, {"NOT_ANALYZED", 0}, {"PASS", 0}, {"REWORK", 0}, {"SYSTEM_ERROR", 0}, {"UNDEFINED", 0}}}, + {"UncertaintyType", {{"COMBINED", 0}, {"MEAN", 0}}}, + {"Uncertainty", {}}, + {"AlarmLimits", {}}, + {"ControlLimits", {}}, + {"SpecificationLimits", {}}, + {"ToolCuttingItem", {}}, + {"LocationAddress", {}}, + {"ActivePowerSource", {}}, + {"LocationNarrative", {}}, + {"Thickness", {}}, + {"LocationSpatialGeographic", {}} }; \ No newline at end of file From 379c3ea6525095d05317a781200e65132d41e2ba Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 7 Oct 2024 16:46:20 -0400 Subject: [PATCH 114/128] First set of merges with main --- src/mtconnect/observation/change_observer.hpp | 1 + src/mtconnect/sink/rest_sink/rest_service.cpp | 3 +- test_package/agent_test.cpp | 85 ------------------- test_package/observation_validation_test.cpp | 1 + 4 files changed, 3 insertions(+), 87 deletions(-) diff --git a/src/mtconnect/observation/change_observer.hpp b/src/mtconnect/observation/change_observer.hpp index c274e848e..5b0dc1ad2 100644 --- a/src/mtconnect/observation/change_observer.hpp +++ b/src/mtconnect/observation/change_observer.hpp @@ -193,6 +193,7 @@ namespace mtconnect::observation { { public: AsyncResponse(std::chrono::milliseconds interval) : m_interval(interval) {} + virtual ~AsyncResponse() = default; virtual bool cancel() = 0; diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 085cbb7a4..86a859f3c 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -544,13 +544,12 @@ namespace mtconnect { auto idHandler = [&](SessionPtr session, RequestPtr request) -> bool { auto asset = request->parameter("assetIds"); - auto pretty = request->parameter("pretty").value_or(false); if (asset) { auto format = request->parameter("format"); auto pretty = request->parameter("pretty").value_or(false); - auto printer = m_sinkContract->getPrinter(acceptFormat(request->m_accepts, format)); + auto printer = getPrinter(request->m_accepts, format); list ids; stringstream str(*asset); diff --git a/test_package/agent_test.cpp b/test_package/agent_test.cpp index d2148493f..7f34a71ef 100644 --- a/test_package/agent_test.cpp +++ b/test_package/agent_test.cpp @@ -3089,48 +3089,6 @@ TEST_F(AgentTest, should_set_sender_from_config_in_XML_header) } } -TEST_F(AgentTest, should_set_validation_flag_in_header_when_version_2_5_validation_on) -{ - auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.5", 4, false, - true, {{configuration::Validation, true}}); - ASSERT_TRUE(agent); - { - PARSE_XML_RESPONSE("/probe"); - ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); - } - - { - PARSE_XML_RESPONSE("/current"); - ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); - } - - { - PARSE_XML_RESPONSE("/sample"); - ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", "true"); - } -} - -TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_version_below_2_5) -{ - auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.4", 4, false, - true, {{configuration::Validation, true}}); - ASSERT_TRUE(agent); - { - PARSE_XML_RESPONSE("/probe"); - ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); - } - - { - PARSE_XML_RESPONSE("/current"); - ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); - } - - { - PARSE_XML_RESPONSE("/sample"); - ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); - } -} - TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_false) { auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.5", 4, false, @@ -3152,28 +3110,6 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_fa } } -TEST_F(AgentTest, should_initialize_observaton_to_initial_value_when_available) -{ - m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.2", 4, true); - - auto device = m_agentTestHelper->getAgent()->getDeviceByName("LinuxCNC"); - ASSERT_TRUE(device); - - addAdapter(); - - { - PARSE_XML_RESPONSE("/current"); - ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:PartCount", "UNAVAILABLE"); - } - - m_agentTestHelper->m_adapter->processData("2024-01-22T20:00:00Z|avail|AVAILABLE"); - - { - PARSE_XML_RESPONSE("/current"); - ASSERT_XML_PATH_EQUAL(doc, "//m:DeviceStream//m:PartCount", "0"); - } -} - TEST_F(AgentTest, should_set_validation_flag_in_header_when_version_2_5_validation_on) { auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.5", 4, false, @@ -3216,27 +3152,6 @@ TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_version_below_2_ } } -TEST_F(AgentTest, should_not_set_validation_flag_in_header_when_validation_is_false) -{ - auto agent = m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.5", 4, false, - true, {{configuration::Validation, false}}); - ASSERT_TRUE(agent); - { - PARSE_XML_RESPONSE("/probe"); - ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); - } - - { - PARSE_XML_RESPONSE("/current"); - ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); - } - - { - PARSE_XML_RESPONSE("/sample"); - ASSERT_XML_PATH_EQUAL(doc, "//m:Header@validation", nullptr); - } -} - TEST_F(AgentTest, should_initialize_observaton_to_initial_value_when_available) { m_agentTestHelper->createAgent("/samples/test_config.xml", 8, 4, "2.2", 4, true); diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index 2c2cb3dcd..4b8da8456 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -59,6 +59,7 @@ class MockPipelineContract : public PipelineContract void deliverObservation(observation::ObservationPtr obs) override {} void deliverAsset(AssetPtr) override {} void deliverDevices(std::list) override {} + void deliverDevice(DevicePtr device) override {} int32_t getSchemaVersion() const override { return m_schemaVersion; } void deliverAssetCommand(entity::EntityPtr) override {} void deliverCommand(entity::EntityPtr) override {} From f2cca5deb5bbaa45bf9d1f24b54419b51964a667 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 7 Oct 2024 17:09:22 -0400 Subject: [PATCH 115/128] Re-merged readme --- README.md | 293 +++++++++++++++++++++++------------------------------- 1 file changed, 125 insertions(+), 168 deletions(-) diff --git a/README.md b/README.md index d7ae3b62e..089b72be4 100755 --- a/README.md +++ b/README.md @@ -680,8 +680,6 @@ Configuration Parameters *Default*: 1 - - #### Adapter General Configuration These can be overridden on a per-adapter basis @@ -1058,128 +1056,6 @@ Sinks { } ``` -### MQTT JSON Ingress Protocol Version 2.0 - -In general the data format will be {"timestamp": "YYYY-MM-DDThh:mm:ssZ","dataItemId":"value", "dataItemId":{"key1":"value1", ..., "keyn":"valuen}} - -**NOTE**: See the standard for the complete description of the fields for the data item representations below. - -A simple set of events and samples will look something like this: - - ```json - { - "timestamp": "2023-11-06T12:12:44Z", //Time Stamp - "tempId": 22.6, //Temperature - "positionId": 1002.345, //X axis position - "executionId": "ACTIVE" //Execution state - } - ``` - -A `CONDITION` requires the key to be the dataItemId and requires the 6 fields as shown in the example below - - ```json - { - "timestamp": "2023-11-06T12:12:44Z", - "dataItemId": { - "level": "fault", - "conditionId":"ac324", - "nativeSeverity": "1000", - "qualifier": "HIGH", - "nativeCode": "ABC", - "message": "something went wrong" - } - } - ``` -A `MESSAGE` requires the key to be the dataItemId and requires the nativeCode field as shown in the example below - - ```json - { - "timestamp": "2023-11-06T12:12:44Z", - "messsageId": { - "nativeCode": "ABC", - "message": "something went wrong" - } - } - ``` - -The `TimeSeries` `REPRESENTATION` requires the key to be the dataItemId and requires 2 fields "count" and "values" and 1 to n comma delimited values. -**NOTE**: The "frequency" field is optional. - - ```json - { - "timestamp": "2023-11-06T12:12:44Z", - "timeSeries1": { - "count": 10, - "frequency": 100, - "values": [1,2,3,4,5,6,7,8,9,10] - } - } - ``` -The `DataSet` `REPRESENTATION` requires the the dataItemId as the key and the "values" field. It may also have the optional "resetTriggered" field. - - ```json - { - { - "timestamp": "2023-11-09T11:20:00Z", - "dataSetId": { - "key1": 123, - "key2": 456, - "key3": 789 - } - } - ``` - - Example with the optional "resetTriggered" filed: - - ```json - { - "timestamp": "2023-11-09T11:20:00Z", - "cncregisterset1": { - "resetTriggered": "NEW", - "value": {"r1":"v1", "r2":"v2", "r3":"v3" } - } - } - ``` - -The `Table` `REPRESENTATION` requires the the dataItemId as the key and the "values" field. It may also have the optional "resetTriggered" field. - - ```json - - { - "timestamp":"2023-11-06T12:12:44Z", - "tableId":{ - "row1":{ - "cell1":"Some Text", - "cell2":3243 - }, - "row2": { - "cell1":"Some Other Text", - "cell2":243 - } - } - } - ``` - - Example with the optional resetTriggered field: - - ```json - { - "timestamp": "2023-11-09T11:20:00Z", - "a1": { - "resetTriggered": "NEW", - "value": { - "r1": { - "k1": 123.45, - "k3": 6789 - }, - "r2": null - } - } - } - ``` - - - * `AdapterIdentity` - Adapter Identity name used to prefix dataitems within the Agent device ids and names. *Default*: @@ -1191,41 +1067,6 @@ The `Table` `REPRESENTATION` requires the the dataItemId as the key and the "val `AdapterIdentity` = ```_ sha1digest({IP}_{PORT})```\ example: `__71020ed1ed` -#### MQTT Adapter/Source - -* `MqttHost` - IP Address or name of the MQTT Broker - - *Default*: 127.0.0.1 - -* `MqttPort` - Port number of MQTT Broker - - *Default*: 1883 - -* `topics` - list of topics to subscribe to. Note : Only raw SHDR strings supported at this time - - *Required* - -* `MqttClientId` - Client ID used when connecting to the MQTT Broker - - *Default*: Auto-generated - - > **⚠️Note:** Mqtt Sinks and Mqtt Adapters create separate connections to their respective brokers, but currently use the same client ID by default. Because of this, when using a single broker for source and sink, best practice is to explicitly specify a distinct `MqttClientId` for each. - > - - > **⚠️Note:** Currently, there is no JSON parser functionality. Agent is expecting a raw SHDR-formatted string - - Example mqtt adapter block: - ```json - mydevice { - Protocol = mqtt - MqttHost = localhost - MqttPort = 1883 - MqttClientId = myUniqueID - Topics = /ingest - } - ``` - - ### Agent Adapter Configuration * `Url` - The URL of the source agent. `http:` or `https:` are accepted for the protocol. @@ -1282,8 +1123,8 @@ logger_config configuration items *Default*: NEVER -Adapter Agent Protocol Version 2.0 -======= +# Agent-Adapter Protocols +## SHDR Version 2.0 The principle adapter data format is a simple plain text stream separated by the pipe character `|`. Every line except for commands starts with an optional timestamp in UTC. If the timestamp is not supplied the agent will supply a timestamp of its own taken at the arrival time of the data to the agent. The remainder of the line is a key followed by data – depending on the type of data item is being written to. @@ -1388,8 +1229,7 @@ Using the quoting conventions explained in the previous section, the inner conte All the reset rules of data set apply to tables and the values are treated as a unit. -Assets ------ +## Assets Assets are associated with a device but do not have a data item they are mapping to. They therefore get the special data item name `@ASSET@`. Assets can be sent either on one line or multiple lines depending on the adapter requirements. The single line form is as follows: @@ -1415,10 +1255,128 @@ Partial updates to assets is also possible by using the @UPDATE_ASSET@ key, but 2012-02-21T23:59:33.460470Z|@UPDATE_ASSET@|KSSP300R.1|OverallToolLength|323.64|CuttingDiameterMax|76.211 -Commands ------ +## MQTT JSON Ingress Protocol Version 2.0 + +In general the data format is {"timestamp": "YYYY-MM-DDThh:mm:ssZ","dataItemId":"value", "dataItemId":{"key1":"value1", ..., "keyn":"valuen}} + +**NOTE**: See the standard for the complete description of the fields for the data item representations below. + +A simple set of events and samples will look something like this: + +```json +{ + "timestamp": "2023-11-06T12:12:44Z", //Time Stamp + "tempId": 22.6, //Temperature + "positionId": 1002.345, //X axis position + "executionId": "ACTIVE" //Execution state +} +``` + +A `CONDITION` requires the key to be the dataItemId and requires the 6 fields as shown in the example below + +```json +{ + "timestamp": "2023-11-06T12:12:44Z", + "dataItemId": { + "level": "fault", + "conditionId":"ac324", + "nativeSeverity": "1000", + "qualifier": "HIGH", + "nativeCode": "ABC", + "message": "something went wrong" + } +} +``` +A `MESSAGE` requires the key to be the dataItemId and requires the nativeCode field as shown in the example below + +```json +{ + "timestamp": "2023-11-06T12:12:44Z", + "messsageId": { + "nativeCode": "ABC", + "message": "something went wrong" + } +} +``` + +The `TimeSeries` `REPRESENTATION` requires the key to be the dataItemId and requires 2 fields "count" and "values" and 1 to n comma delimited values. +>**NOTE**: The "frequency" field is optional. + +```json +{ + "timestamp": "2023-11-06T12:12:44Z", + "timeSeries1": { + "count": 10, + "frequency": 100, + "values": [1,2,3,4,5,6,7,8,9,10] + } +} +``` +The `DataSet` `REPRESENTATION` requires the the dataItemId as the key and the "values" field. It may also have the optional "resetTriggered" field. + +```json +{ +{ + "timestamp": "2023-11-09T11:20:00Z", + "dataSetId": { + "key1": 123, + "key2": 456, + "key3": 789 + } +} +``` + +Example with the optional "resetTriggered" filed: + +```json +{ + "timestamp": "2023-11-09T11:20:00Z", + "cncregisterset1": { + "resetTriggered": "NEW", + "value": {"r1":"v1", "r2":"v2", "r3":"v3" } + } +} +``` + +The `Table` `REPRESENTATION` requires the the dataItemId as the key and the "values" field. It may also have the optional "resetTriggered" field. + +```json + +{ + "timestamp":"2023-11-06T12:12:44Z", + "tableId":{ + "row1":{ + "cell1":"Some Text", + "cell2":3243 + }, + "row2": { + "cell1":"Some Other Text", + "cell2":243 + } + } +} +``` + +Example with the optional resetTriggered field: + +```json +{ + "timestamp": "2023-11-09T11:20:00Z", + "a1": { + "resetTriggered": "NEW", + "value": { + "r1": { + "k1": 123.45, + "k3": 6789 + }, + "r2": null + } + } +} +``` -There are a number of commands that can be sent as part of the adapter stream. These change some dynamic elements of the device information, the interpretation of the data, or the associated default device. Commands are given on a single line starting with an asterisk `* ` as the first character of the line and followed by a : . They are as follows: +## Adapter Commands +There are a number of commands that can be sent as part of the adapter stream over the SHDR port connection. These change some dynamic elements of the device information, the interpretation of the data, or the associated default device. Commands are given on a single line starting with an asterisk `* ` as the first character of the line and followed by a : . They are as follows: * Specify the Adapter Software Version the adapter supports: @@ -1482,8 +1440,7 @@ There are a number of commands that can be sent as part of the adapter stream. T Any other command will be logged as a warning. -Protocol ----- +## Heartbeat Protocol The agent and the adapter have a heartbeat that makes sure each is responsive to properly handle disconnects in a timely manner. The Heartbeat frequency is set by the adapter and honored by the agent. When the agent connects to the adapter, it first sends a `* PING` and then expects the response `* PONG ` where `` is specified in milliseconds. So if the following communications are given: From 672c3f365599511559a512124bbba6463e619b6d Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 7 Oct 2024 17:32:02 -0400 Subject: [PATCH 116/128] Merged changes from main-dev and added support for introduced. --- src/mtconnect/pipeline/validator.hpp | 12 ++++++++++-- src/mtconnect/validation/observations.hpp | 2 +- test_package/observation_validation_test.cpp | 18 ++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index 44c02becf..352cc30f6 100644 --- a/src/mtconnect/pipeline/validator.hpp +++ b/src/mtconnect/pipeline/validator.hpp @@ -70,10 +70,18 @@ namespace mtconnect::pipeline { auto lit = lits.find(value); if (lit != lits.end()) { - evt->setProperty("quality", std::string("VALID")); + // Check if it has not been introduced yet + if (lit->second.first > 0 && m_contract->getSchemaVersion() < lit->second.first) + { + evt->setProperty("quality", std::string("INVALID")); + } + else + { + evt->setProperty("quality", std::string("VALID")); + } // Check if deprecated - if (lit->second > 0 && m_contract->getSchemaVersion() > lit->second) + if (lit->second.second > 0 && m_contract->getSchemaVersion() >= lit->second.second) { evt->setProperty("deprecated", true); } diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index c5a843edd..c6df2c858 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -31,7 +31,7 @@ namespace mtconnect { namespace observations { /// @brief Validation type for observations - using Validation = std::unordered_map>; + using Validation = std::unordered_map>>; /// @brief Global Validations for Event Observation's Controlled Vocabularies /// diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index 4b8da8456..1fe9c7fab 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -219,3 +219,21 @@ TEST_F(ObservationValidationTest, should_not_validate_tables) auto quality = evt->get("quality"); ASSERT_EQ("VALID", quality); } + +TEST_F(ObservationValidationTest, should_be_invalid_if_entry_has_not_been_introduced_yet) +{ + ErrorList errors; + m_dataItem = + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, errors); + + auto contract = static_cast(m_context->m_contract.get()); + contract->m_schemaVersion = SCHEMA_VERSION(1, 4); + + auto event = Observation::make(m_dataItem, {{"VALUE", "WAIT"s}}, m_time, errors); + + auto evt = (*m_validator)(std::move(event)); + auto quality = evt->get("quality"); + ASSERT_EQ("INVALID", quality); + ASSERT_FALSE(evt->hasProperty("deprecated")); +} + From bea5c136e1ff74702d316bb1b7c35e10fb124324 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Thu, 3 Oct 2024 16:54:08 -0400 Subject: [PATCH 117/128] Exit when agent encounters malformed url in configuration file --- src/mtconnect/configuration/agent_config.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index 9052398d8..9828cf162 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -910,7 +910,15 @@ namespace mtconnect::configuration { auto parsed = Url::parse(url); options[configuration::Protocol] = parsed.m_protocol; - options[configuration::Host] = parsed.getHost(); + + auto host = parsed.getHost(); + if (host.empty()) + { + LOG(fatal) << "Malformed URL in configuration file: '" << url << "', exiting"; + exit(1); + } + options[configuration::Host] = host; + if (parsed.m_port) options[configuration::Port] = parsed.getPort(); if (parsed.m_path != "/") From 0914558fe0550f5fce47e17deb0f94bbb1096bce Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 18 Nov 2024 08:57:48 -0500 Subject: [PATCH 118/128] Added access to agent hooks in sink contract --- demo/agent/mazak.txt | 1 - src/mtconnect/agent.hpp | 39 +++++++++++++++++++++++++++++++++++++ src/mtconnect/sink/sink.hpp | 16 +++++++++++++++ styles/styles.xsl | 6 +++--- 4 files changed, 58 insertions(+), 4 deletions(-) diff --git a/demo/agent/mazak.txt b/demo/agent/mazak.txt index f293f5f5d..1720b21e5 100644 --- a/demo/agent/mazak.txt +++ b/demo/agent/mazak.txt @@ -1,4 +1,3 @@ -=~=~=~=~=~=~=~=~=~=~=~= PuTTY log 2022.02.02 14:04:20 =~=~=~=~=~=~=~=~=~=~=~= * uuid: 342072d3-5a0b-f184-2de1-d6f24108c59f * manufacturer: Mazak_Corporation * description: Variaxis w/SMooth-AI diff --git a/src/mtconnect/agent.hpp b/src/mtconnect/agent.hpp index 6fd347651..d173e8377 100644 --- a/src/mtconnect/agent.hpp +++ b/src/mtconnect/agent.hpp @@ -658,6 +658,45 @@ namespace mtconnect { } buffer::CircularBuffer &getCircularBuffer() override { return m_agent->getCircularBuffer(); } + + configuration::HookManager &getHooks(HookType type) override + { + using namespace sink; + switch (type) + { + case BEFORE_START: + return m_agent->beforeStartHooks(); + break; + + case BEFORE_STOP: + return m_agent->beforeStopHooks(); + break; + + case BEFORE_DEVICE_XML_UPDATE: + return m_agent->beforeDeviceXmlUpdateHooks(); + break; + + case AFTER_DEVICE_XML_UPDATE: + return m_agent->afterDeviceXmlUpdateHooks(); + break; + + case BEFORE_INITIALIZE: + return m_agent->beforeInitializeHooks(); + break; + + case AFTER_INITIALIZE: + return m_agent->afterInitializeHooks(); + break; + } + + LOG(error) << "getHooks: Bad hook manager type given to sink contract"; + throw std::runtime_error("getHooks: Bad hook manager type"); + + // Never gets here. + static configuration::HookManager NullHooks; + return NullHooks; + } + protected: Agent *m_agent; diff --git a/src/mtconnect/sink/sink.hpp b/src/mtconnect/sink/sink.hpp index c06d0e1c4..19766e568 100644 --- a/src/mtconnect/sink/sink.hpp +++ b/src/mtconnect/sink/sink.hpp @@ -31,6 +31,7 @@ #include "mtconnect/device_model/device.hpp" #include "mtconnect/observation/observation.hpp" #include "mtconnect/printer//printer.hpp" +#include "mtconnect/configuration/hook_manager.hpp" namespace mtconnect { namespace printer { @@ -46,6 +47,7 @@ namespace mtconnect { namespace buffer { class CircularBuffer; } + class Agent; /// @brief The Sink namespace for outgoing data from the agent namespace sink { @@ -53,6 +55,15 @@ namespace mtconnect { class AGENT_LIB_API SinkContract { public: + enum HookType { + BEFORE_STOP, + BEFORE_START, + BEFORE_DEVICE_XML_UPDATE, + AFTER_DEVICE_XML_UPDATE, + BEFORE_INITIALIZE, + AFTER_INITIALIZE + }; + virtual ~SinkContract() = default; /// @brief get the printer for a mime type. Current options: `xml` or `json`. /// @param[in] aType a string for the type @@ -102,6 +113,11 @@ namespace mtconnect { /// @brief Get a pointer to the asset storage /// @return a pointer to the asset storage. virtual const asset::AssetStorage *getAssetStorage() = 0; + + /// @brief Get a reference to the hook manager for the agent. + /// @param[in] type the type manager to retrieve + /// @return a reference to the hook manager + virtual configuration::HookManager &getHooks(HookType type) = 0; /// @brief Shared pointer to the pipeline context std::shared_ptr m_pipelineContext; diff --git a/styles/styles.xsl b/styles/styles.xsl index 066277230..2be09db28 100644 --- a/styles/styles.xsl +++ b/styles/styles.xsl @@ -4,9 +4,9 @@ xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" - xmlns:m="urn:mtconnect.org:MTConnectDevices:2.2" - xmlns:s="urn:mtconnect.org:MTConnectStreams:2.2" - xmlns:e="urn:mtconnect.org:MTConnectError:2.2" + xmlns:m="urn:mtconnect.org:MTConnectDevices:2.3" + xmlns:s="urn:mtconnect.org:MTConnectStreams:2.3" + xmlns:e="urn:mtconnect.org:MTConnectError:2.3" xmlns:js="urn:custom-javascript" exclude-result-prefixes="msxsl js" xmlns:msxsl="urn:schemas-microsoft-com:xslt" From cd9408dbefc3fd38eddfd7fc2ac236998ea56406 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Mon, 18 Nov 2024 13:25:46 -0500 Subject: [PATCH 119/128] Added after start hook --- src/mtconnect/agent.cpp | 2 ++ src/mtconnect/agent.hpp | 9 +++++++++ src/mtconnect/sink/sink.hpp | 1 + 3 files changed, 12 insertions(+) diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index e842a7855..2cdc88cdf 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -242,6 +242,8 @@ namespace mtconnect { // Start all the sources for (auto source : m_sources) source->start(); + + m_afterStartHooks.exec(*this); } catch (std::runtime_error &e) { diff --git a/src/mtconnect/agent.hpp b/src/mtconnect/agent.hpp index d173e8377..de9f1a85d 100644 --- a/src/mtconnect/agent.hpp +++ b/src/mtconnect/agent.hpp @@ -112,6 +112,10 @@ namespace mtconnect { /// @brief Hooks to run when before the agent starts all the soures and sinks /// @return configuration::HookManager& auto &beforeStartHooks() { return m_beforeStartHooks; } + + /// @brief Hooks to run when after the agent starts all the soures and sinks + /// @return configuration::HookManager& + auto &afterStartHooks() { return m_afterStartHooks; } /// @brief Hooks before the agent stops all the sources and sinks /// @return configuration::HookManager& @@ -549,6 +553,7 @@ namespace mtconnect { configuration::HookManager m_beforeInitializeHooks; configuration::HookManager m_afterInitializeHooks; configuration::HookManager m_beforeStartHooks; + configuration::HookManager m_afterStartHooks; configuration::HookManager m_beforeStopHooks; configuration::HookManager m_beforeDeviceXmlUpdateHooks; configuration::HookManager m_afterDeviceXmlUpdateHooks; @@ -668,6 +673,10 @@ namespace mtconnect { return m_agent->beforeStartHooks(); break; + case AFTER_START: + return m_agent->afterStartHooks(); + break; + case BEFORE_STOP: return m_agent->beforeStopHooks(); break; diff --git a/src/mtconnect/sink/sink.hpp b/src/mtconnect/sink/sink.hpp index 19766e568..4678cde16 100644 --- a/src/mtconnect/sink/sink.hpp +++ b/src/mtconnect/sink/sink.hpp @@ -58,6 +58,7 @@ namespace mtconnect { enum HookType { BEFORE_STOP, BEFORE_START, + AFTER_START, BEFORE_DEVICE_XML_UPDATE, AFTER_DEVICE_XML_UPDATE, BEFORE_INITIALIZE, From 02c09dec8b46dc0e10fa1d82b456347fed70677b Mon Sep 17 00:00:00 2001 From: Simon Yeung Date: Tue, 19 Nov 2024 10:02:34 -0800 Subject: [PATCH 120/128] Use log channel to divide traffic for various plugin logging and clean up legacy code --- src/mtconnect/configuration/agent_config.cpp | 152 ++++++++++++------- src/mtconnect/configuration/agent_config.hpp | 55 ++++--- src/mtconnect/logging.hpp | 31 ++-- 3 files changed, 147 insertions(+), 91 deletions(-) diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index 9828cf162..e83bd9ff6 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -100,8 +100,6 @@ BOOST_LOG_ATTRIBUTE_KEYWORD(named_scope, "Scope", logr::attributes::named_scope: BOOST_LOG_ATTRIBUTE_KEYWORD(utc_timestamp, "Timestamp", logr::attributes::utc_clock::value_type); namespace mtconnect::configuration { - AGENT_LIB_API - boost::log::trivial::logger_type *gAgentLogger = nullptr; AgentConfiguration::AgentConfiguration() : m_context {make_unique()}, m_monitorTimer(m_context->get()) @@ -233,8 +231,10 @@ namespace mtconnect::configuration { #endif m_context.reset(); - if (m_sink) - m_sink.reset(); + for (auto &[channelName, logChannel] : m_logChannels) + logChannel.m_logSink.reset(); + + m_logChannels.clear(); logr::core::get()->remove_all_sinks(); } @@ -431,8 +431,10 @@ namespace mtconnect::configuration { void AgentConfiguration::setLoggingLevel(const logr::trivial::severity_level level) { using namespace logr::trivial; - m_logLevel = level; - logr::core::get()->set_filter(severity >= level); + for ( auto &[channelName, logChannel] : m_logChannels) + { + logChannel.m_logLevel = level; + } } static logr::trivial::severity_level StringToLogLevel(const std::string &level) @@ -474,11 +476,9 @@ namespace mtconnect::configuration { void AgentConfiguration::configureLogger(const ptree &config) { using namespace logr::trivial; - namespace kw = boost::log::keywords; namespace expr = logr::expressions; logr::core::get()->remove_all_sinks(); - m_sink.reset(); //// Add the commonly used attributes; includes TimeStamp, ProcessID and ThreadID and others logr::add_common_attributes(); @@ -487,12 +487,43 @@ namespace mtconnect::configuration { logr::attributes::current_thread_id()); logr::core::get()->add_global_attribute("Timestamp", logr::attributes::utc_clock()); + m_logger = &::boost::log::trivial::logger::get(); + + setLoggingLevel(severity_level::info); + + auto formatter = + expr::stream << expr::format_date_time("Timestamp", + "%Y-%m-%dT%H:%M:%S.%fZ ") + << "(" + << expr::attr("ThreadID") + << ") [" << severity << "] " << named_scope << ": " << expr::smessage; + + configureLoggerChannel("agent", config, formatter); + } + + void AgentConfiguration::configureLoggerChannel(const std::string &channelName, const ptree &config, std::optional> formatter) + { + using namespace logr::trivial; + namespace expr = logr::expressions; + namespace kw = boost::log::keywords; + + auto &logChannel = m_logChannels[channelName]; + if (logChannel.m_channelName == "") + logChannel.m_channelName = channelName; + + if (!formatter) + { + formatter = + expr::stream << expr::format_date_time("Timestamp", + "%Y-%m-%dT%H:%M:%S.%fZ ") + << std::setw(7) << std::left << boost::log::trivial::severity << " " << expr::message; + } + ptree empty; auto logger = config.get_child_optional("logger_config").value_or(empty); - setLoggingLevel(severity_level::info); - static const string defaultFileName {"agent.log"}; - static const string defaultArchivePattern("agent_%Y-%m-%d_%H-%M-%S_%N.log"); + const string defaultFileName = channelName + ".log"; + const string defaultArchivePattern = channelName + "_%Y-%m-%d_%H-%M-%S_%N.log"; ConfigOptions options; AddDefaultedOptions(logger, options, @@ -505,19 +536,10 @@ namespace mtconnect::configuration { {{"output", string()}, {"level", string()}, {"logging_level", string()}}); auto output = GetOption(options, "output"); - auto level = setLoggingLevel( + auto level = StringToLogLevel( GetOption(options, "level") .value_or(GetOption(options, "logging_level").value_or("info"s))); - gAgentLogger = m_logger = &::boost::log::trivial::logger::get(); - - auto formatter = - expr::stream << expr::format_date_time("Timestamp", - "%Y-%m-%dT%H:%M:%S.%fZ ") - << "(" - << expr::attr("ThreadID") - << ") [" << severity << "] " << named_scope << ": " << expr::smessage; - if (m_isDebug || (output && (*output == "cout" || *output == "cerr"))) { ostream *out; @@ -526,11 +548,21 @@ namespace mtconnect::configuration { else out = &std::cout; - logr::add_console_log(*out, kw::format = formatter, kw::auto_flush = true); - if (m_isDebug && level >= severity_level::debug) - setLoggingLevel(severity_level::debug); + level = severity_level::debug; + + auto sink = boost::make_shared(); + logChannel.m_logSink = sink; + logChannel.m_logLevel = level; + logChannel.m_logFileName = output.value(); + + sink->locked_backend()->add_stream(boost::shared_ptr(out, boost::null_deleter())); + sink->locked_backend()->auto_flush(true); + + sink->set_formatter(formatter.value()); + sink->set_filter(expr::attr("Channel") == logChannel.m_channelName && severity >= logChannel.m_logLevel); + logr::core::get()->add_sink(sink); return; } @@ -558,16 +590,23 @@ namespace mtconnect::configuration { } } - m_maxLogFileSize = ConvertFileSize(options, "max_size", m_maxLogFileSize); - m_logRotationSize = ConvertFileSize(options, "rotation_size", m_logRotationSize); + auto &maxLogFileSize = logChannel.m_maxLogFileSize; + auto &logRotationSize = logChannel.m_logRotationSize; + auto &rotationLogInterval = logChannel.m_rotationLogInterval; + auto &logArchivePattern = logChannel.m_logArchivePattern; + auto &logDirectory = logChannel.m_logDirectory; + auto &logFileName = logChannel.m_logFileName; + + maxLogFileSize = ConvertFileSize(options, "max_size", maxLogFileSize); + logRotationSize = ConvertFileSize(options, "rotation_size", logRotationSize); int max_index = *GetOption(options, "max_index"); if (auto sched = GetOption(options, "schedule")) { if (*sched == "DAILY") - m_rotationLogInterval = 24; + rotationLogInterval = 24; else if (*sched == "WEEKLY") - m_rotationLogInterval = 168; + rotationLogInterval = 168; else if (*sched != "NEVER") LOG(error) << "Invalid schedule value."; } @@ -576,52 +615,55 @@ namespace mtconnect::configuration { auto file_name = *GetOption(options, "file_name"); auto archive_pattern = *GetOption(options, "archive_pattern"); - m_logArchivePattern = fs::path(archive_pattern); - if (!m_logArchivePattern.has_filename()) + logArchivePattern = fs::path(archive_pattern); + if (!logArchivePattern.has_filename()) { - m_logArchivePattern = - m_logArchivePattern / archiveFileName(get(options["file_name"])); + logArchivePattern = + logArchivePattern / archiveFileName(get(options["file_name"])); } - if (m_logArchivePattern.is_relative()) - m_logArchivePattern = fs::current_path() / m_logArchivePattern; + if (logArchivePattern.is_relative()) + logArchivePattern = fs::current_path() / logArchivePattern; // Get the log directory from the archive path. - m_logDirectory = m_logArchivePattern.parent_path(); + logDirectory = logArchivePattern.parent_path(); // If the file name does not specify a log directory, use the // archive directory - m_logFileName = fs::path(file_name); - if (!m_logFileName.has_parent_path()) - m_logFileName = m_logDirectory / m_logFileName; - else if (m_logFileName.is_relative()) - m_logFileName = fs::current_path() / m_logFileName; - - boost::shared_ptr core = logr::core::get(); + logFileName = fs::path(file_name); + if (!logFileName.has_parent_path()) + logFileName = logDirectory / logFileName; + else if (logFileName.is_relative()) + logFileName = fs::current_path() / logFileName; // Create a text file sink - m_sink = boost::make_shared( - kw::file_name = m_logFileName, kw::target_file_name = m_logArchivePattern.filename(), - kw::auto_flush = true, kw::rotation_size = m_logRotationSize, + auto sink = boost::make_shared( + kw::file_name = logFileName, kw::target_file_name = logArchivePattern.filename(), + kw::auto_flush = true, kw::rotation_size = logRotationSize, kw::open_mode = ios_base::out | ios_base::app, kw::format = formatter); + logChannel.m_logSink = sink; + logChannel.m_logLevel = level; + // Set up where the rotated files will be stored - m_sink->locked_backend()->set_file_collector(logr::sinks::file::make_collector( - kw::target = m_logDirectory, kw::max_size = m_maxLogFileSize, kw::max_files = max_index)); + sink->locked_backend()->set_file_collector(logr::sinks::file::make_collector( + kw::target = logDirectory, kw::max_size = maxLogFileSize, kw::max_files = max_index)); - if (m_rotationLogInterval > 0) + if (rotationLogInterval > 0) { - m_sink->locked_backend()->set_time_based_rotation( + sink->locked_backend()->set_time_based_rotation( logr::sinks::file::rotation_at_time_interval( - boost::posix_time::hours(m_rotationLogInterval))); + boost::posix_time::hours(rotationLogInterval))); } // Upon restart, scan the target directory for files matching the file_name pattern - m_sink->locked_backend()->scan_for_files(); - m_sink->set_formatter(formatter); + sink->locked_backend()->scan_for_files(); + + sink->set_formatter(formatter.value()); + sink->set_filter(expr::attr("Channel") == logChannel.m_channelName && severity >= logChannel.m_logLevel); // Formatter for the logger - core->add_sink(m_sink); + logr::core::get()->add_sink(sink); } static std::string ExpandValue(const std::map &values, @@ -734,8 +776,8 @@ namespace mtconnect::configuration { cerr << "could not load config file: " << e.what() << endl; throw e; } - // if (!m_loggerFile) - if (!m_sink) + + if (m_logChannels.empty()) { configureLogger(config); } diff --git a/src/mtconnect/configuration/agent_config.hpp b/src/mtconnect/configuration/agent_config.hpp index dd68f198f..2e7fffd73 100644 --- a/src/mtconnect/configuration/agent_config.hpp +++ b/src/mtconnect/configuration/agent_config.hpp @@ -110,8 +110,15 @@ namespace mtconnect { void initialize(const boost::program_options::variables_map &options) override; /// @brief Configure the logger with the config node from the config file + /// @param channelName the log channel name + /// @param config the configuration node + /// @param formatter optional custom message format + void configureLoggerChannel(const std::string &channelName, const ptree &config, std::optional> formatter = std::nullopt); + + /// @brief Configure the agent logger with the config node from the config file /// @param config the configuration node void configureLogger(const ptree &config); + /// @brief load a configuration text /// @param[in] text the configuration text loaded from a file /// @param[in] fmt the file format, can be MTCONNECT, JSON, or XML @@ -148,22 +155,22 @@ namespace mtconnect { ///@{ /// @brief gets the boost log sink /// @return boost log sink - const auto &getLoggerSink() const { return m_sink; } + const auto &getLoggerSink(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logSink; } /// @brief gets the log directory /// @return log directory - const auto &getLogDirectory() const { return m_logDirectory; } + const auto &getLogDirectory(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logDirectory; } /// @brief get the logging file name /// @return log file name - const auto &getLogFileName() const { return m_logFileName; } + const auto &getLogFileName(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logFileName; } /// @brief for log rolling, get the log archive pattern /// @return log archive pattern - const auto &getLogArchivePattern() const { return m_logArchivePattern; } + const auto &getLogArchivePattern(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logArchivePattern; } /// @brief Get the maximum size of all the log files /// @return the maximum size of all log files - auto getMaxLogFileSize() const { return m_maxLogFileSize; } + auto getMaxLogFileSize(const std::string &channelName = "agent") { return m_logChannels[channelName].m_maxLogFileSize; } /// @brief the maximum size of a log file when it triggers rolling over /// @return the maxumum site of a log file - auto getLogRotationSize() const { return m_logRotationSize; } + auto getLogRotationSize(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logRotationSize; } /// @brief How often to roll over the log file /// /// One of: @@ -172,10 +179,10 @@ namespace mtconnect { /// - `NEVER` /// /// @return the log file interval - auto getRotationLogInterval() const { return m_rotationLogInterval; } + auto getRotationLogInterval(const std::string &channelName = "agent") { return m_logChannels[channelName].m_rotationLogInterval; } /// @brief Get the current log level /// @return log level - auto getLogLevel() const { return m_logLevel; } + auto getLogLevel(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logLevel; } /// @brief set the logging level /// @param[in] level the new logging level @@ -308,6 +315,25 @@ namespace mtconnect { protected: using text_sink = boost::log::sinks::synchronous_sink; + using console_sink = boost::log::sinks::synchronous_sink; + + struct LogChannel + { + std::string m_channelName; + std::filesystem::path m_logDirectory; + std::filesystem::path m_logArchivePattern; + std::filesystem::path m_logFileName; + + int64_t m_maxLogFileSize {0}; + int64_t m_logRotationSize {0}; + int64_t m_rotationLogInterval {0}; + + boost::log::trivial::severity_level m_logLevel {boost::log::trivial::severity_level::info}; + + boost::shared_ptr m_logSink; + }; + + std::map m_logChannels; std::map m_initializers; @@ -316,7 +342,7 @@ namespace mtconnect { pipeline::PipelineContextPtr m_pipelineContext; std::unique_ptr m_adapterHandler; - boost::shared_ptr m_sink; + std::string m_version; std::string m_devicesFile; std::filesystem::path m_exePath; @@ -335,17 +361,6 @@ namespace mtconnect { std::optional m_configTime; std::optional m_deviceTime; - // Logging info for testing - std::filesystem::path m_logDirectory; - std::filesystem::path m_logFileName; - std::filesystem::path m_logArchivePattern; - - boost::log::trivial::severity_level m_logLevel {boost::log::trivial::severity_level::info}; - - int64_t m_maxLogFileSize {0}; - int64_t m_logRotationSize {0}; - int64_t m_rotationLogInterval {0}; - // Factories sink::SinkFactory m_sinkFactory; source::SourceFactory m_sourceFactory; diff --git a/src/mtconnect/logging.hpp b/src/mtconnect/logging.hpp index 5e2d613f2..c7247e8a8 100644 --- a/src/mtconnect/logging.hpp +++ b/src/mtconnect/logging.hpp @@ -22,28 +22,27 @@ #include #include +#include +#include #include "mtconnect/config.hpp" -/// @brief synonym for `BOOST_LOG_TRIVIAL` -#define LOG BOOST_LOG_TRIVIAL +typedef boost::log::sources::severity_channel_logger_mt +< + boost::log::trivial::severity_level, // the type of the severity level + std::string // the type of the channel name +> channel_logger_mt; + +BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(agent_logger, channel_logger_mt) +{ + // Specify the channel name on construction, similarly as with the channel_logger + return channel_logger_mt(boost::log::keywords::channel = "agent"); +} + +#define LOG(lvl) BOOST_LOG_SEV(agent_logger::get(), ::boost::log::trivial::lvl) /// @brief synonym for `BOOST_LOG_NAMED_SCOPE` #define NAMED_SCOPE BOOST_LOG_NAMED_SCOPE -// Must be initialized in the plugin before callign log as follows: -// mtconnect::gAgentLogger = config->getLogger(); -// After that, use PLUGIN_LOG(lvl) << ...; -namespace mtconnect { - namespace configuration { - AGENT_LIB_API - extern boost::log::trivial::logger_type *gAgentLogger; - } // namespace configuration -} // namespace mtconnect - #define LOG_LEVEL(lvl) ::boost::log::trivial::lvl -/// @brief Used when static using static agent_lib in a plugin shared object -#define PLUGIN_LOG(lvl) \ - BOOST_LOG_STREAM_WITH_PARAMS(*mtconnect::configuration::gAgentLogger, \ - (::boost::log::keywords::severity = ::boost::log::trivial::lvl)) From 28d05c781d77b0c7fc11605e59675edd5caec6c9 Mon Sep 17 00:00:00 2001 From: Simon Yeung Date: Tue, 19 Nov 2024 12:31:16 -0800 Subject: [PATCH 121/128] update tests --- test_package/testadapter_service.hpp | 2 -- test_package/testsink_service.hpp | 2 -- 2 files changed, 4 deletions(-) diff --git a/test_package/testadapter_service.hpp b/test_package/testadapter_service.hpp index 347324036..d0828588a 100644 --- a/test_package/testadapter_service.hpp +++ b/test_package/testadapter_service.hpp @@ -62,8 +62,6 @@ namespace mtconnect { static void register_factory(const boost::property_tree::ptree &block, configuration::AgentConfiguration &config) { - mtconnect::configuration::gAgentLogger = config.getLogger(); - PLUGIN_LOG(debug) << "Registering adapter factory for adapter_plugin_test"; config.getSourceFactory().registerFactory("adapter_plugin_test", &adapter_plugin_test::create); } diff --git a/test_package/testsink_service.hpp b/test_package/testsink_service.hpp index 87b6d551e..9b79806e2 100644 --- a/test_package/testsink_service.hpp +++ b/test_package/testsink_service.hpp @@ -51,8 +51,6 @@ namespace mtconnect { static void register_factory(const boost::property_tree::ptree &block, configuration::AgentConfiguration &config) { - mtconnect::configuration::gAgentLogger = config.getLogger(); - PLUGIN_LOG(debug) << "Registering sink factory for sink_plugin_test"; config.getSinkFactory().registerFactory("sink_plugin_test", &sink_plugin_test::create); } }; From 54bb90227f02876bc8cb75d82219db8e93d3b14d Mon Sep 17 00:00:00 2001 From: Simon Yeung Date: Tue, 19 Nov 2024 12:45:52 -0800 Subject: [PATCH 122/128] define CHANNEL_LOGGER_INIT --- src/mtconnect/logging.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/mtconnect/logging.hpp b/src/mtconnect/logging.hpp index c7247e8a8..c0e1f9f73 100644 --- a/src/mtconnect/logging.hpp +++ b/src/mtconnect/logging.hpp @@ -33,11 +33,11 @@ typedef boost::log::sources::severity_channel_logger_mt std::string // the type of the channel name > channel_logger_mt; -BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(agent_logger, channel_logger_mt) -{ - // Specify the channel name on construction, similarly as with the channel_logger - return channel_logger_mt(boost::log::keywords::channel = "agent"); -} +#define CHANNEL_LOGGER_INIT(logger, channelName) \ +BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(logger, channel_logger_mt) \ +{ return channel_logger_mt(boost::log::keywords::channel = channelName); } + +CHANNEL_LOGGER_INIT(agent_logger, "agent") #define LOG(lvl) BOOST_LOG_SEV(agent_logger::get(), ::boost::log::trivial::lvl) From db2124651bb586843d468071b92252ad07660e77 Mon Sep 17 00:00:00 2001 From: Simon Yeung Date: Tue, 19 Nov 2024 14:52:15 -0800 Subject: [PATCH 123/128] fix a regression exception --- src/mtconnect/configuration/agent_config.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index e83bd9ff6..9e1db5372 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -430,11 +430,8 @@ namespace mtconnect::configuration { void AgentConfiguration::setLoggingLevel(const logr::trivial::severity_level level) { - using namespace logr::trivial; for ( auto &[channelName, logChannel] : m_logChannels) - { logChannel.m_logLevel = level; - } } static logr::trivial::severity_level StringToLogLevel(const std::string &level) @@ -478,19 +475,19 @@ namespace mtconnect::configuration { using namespace logr::trivial; namespace expr = logr::expressions; - logr::core::get()->remove_all_sinks(); + auto core = logr::core::get(); + + core->remove_all_sinks(); //// Add the commonly used attributes; includes TimeStamp, ProcessID and ThreadID and others logr::add_common_attributes(); - logr::core::get()->add_global_attribute("Scope", logr::attributes::named_scope()); - logr::core::get()->add_global_attribute(logr::aux::default_attribute_names::thread_id(), + core->add_global_attribute("Scope", logr::attributes::named_scope()); + core->add_global_attribute(logr::aux::default_attribute_names::thread_id(), logr::attributes::current_thread_id()); - logr::core::get()->add_global_attribute("Timestamp", logr::attributes::utc_clock()); + core->add_global_attribute("Timestamp", logr::attributes::utc_clock()); m_logger = &::boost::log::trivial::logger::get(); - setLoggingLevel(severity_level::info); - auto formatter = expr::stream << expr::format_date_time("Timestamp", "%Y-%m-%dT%H:%M:%S.%fZ ") @@ -554,7 +551,7 @@ namespace mtconnect::configuration { auto sink = boost::make_shared(); logChannel.m_logSink = sink; logChannel.m_logLevel = level; - logChannel.m_logFileName = output.value(); + logChannel.m_logFileName = output.value_or("debug"); sink->locked_backend()->add_stream(boost::shared_ptr(out, boost::null_deleter())); sink->locked_backend()->auto_flush(true); From d54a31e0123229fe13611dc2a8d957df2b9ddf32 Mon Sep 17 00:00:00 2001 From: Simon Yeung Date: Wed, 20 Nov 2024 09:31:36 -0800 Subject: [PATCH 124/128] remove getLogger() --- src/mtconnect/configuration/agent_config.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/mtconnect/configuration/agent_config.hpp b/src/mtconnect/configuration/agent_config.hpp index 2e7fffd73..071391472 100644 --- a/src/mtconnect/configuration/agent_config.hpp +++ b/src/mtconnect/configuration/agent_config.hpp @@ -192,10 +192,6 @@ namespace mtconnect { /// @return the logging level boost::log::trivial::severity_level setLoggingLevel(const std::string &level); - /// @brief get a pointer to the logger - boost::log::trivial::logger_type *getLogger() { return m_logger; } - ///@} - std::optional findConfigFile(const std::string &file) { return findFile(m_configPaths, file); From 5c87f6bacb5ee5a0cc331731192827c9a4a63c68 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 15 Jan 2025 15:50:21 -0500 Subject: [PATCH 125/128] Added physical asset --- agent_lib/CMakeLists.txt | 2 + src/mtconnect/asset/cutting_tool.hpp | 1 + src/mtconnect/asset/physical_asset.cpp | 80 +++++++++ src/mtconnect/asset/physical_asset.hpp | 40 +++++ src/mtconnect/entity/xml_parser.cpp | 2 +- test_package/CMakeLists.txt | 1 + test_package/physical_asset_test.cpp | 234 +++++++++++++++++++++++++ 7 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 src/mtconnect/asset/physical_asset.cpp create mode 100644 src/mtconnect/asset/physical_asset.hpp create mode 100644 test_package/physical_asset_test.cpp diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index dc8316917..e9340aa72 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -25,6 +25,7 @@ set(AGENT_SOURCES "${SOURCE_DIR}/asset/raw_material.hpp" "${SOURCE_DIR}/asset/qif_document.hpp" "${SOURCE_DIR}/asset/component_configuration_parameters.hpp" + "${SOURCE_DIR}/asset/physical_asset.hpp" # src/asset SOURCE_FILES_ONLY @@ -34,6 +35,7 @@ set(AGENT_SOURCES "${SOURCE_DIR}/asset/raw_material.cpp" "${SOURCE_DIR}/asset/qif_document.cpp" "${SOURCE_DIR}/asset/component_configuration_parameters.cpp" + "${SOURCE_DIR}/asset/physical_asset.cpp" # src/buffer HEADER_FILES_ONLY diff --git a/src/mtconnect/asset/cutting_tool.hpp b/src/mtconnect/asset/cutting_tool.hpp index 7eec093e6..4af45f8d0 100644 --- a/src/mtconnect/asset/cutting_tool.hpp +++ b/src/mtconnect/asset/cutting_tool.hpp @@ -24,6 +24,7 @@ #include "asset.hpp" #include "mtconnect/config.hpp" #include "mtconnect/utilities.hpp" +#include "mtconnect/asset/physical_asset.hpp" namespace mtconnect { namespace asset { diff --git a/src/mtconnect/asset/physical_asset.cpp b/src/mtconnect/asset/physical_asset.cpp new file mode 100644 index 000000000..c51b09bd7 --- /dev/null +++ b/src/mtconnect/asset/physical_asset.cpp @@ -0,0 +1,80 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "mtconnect/asset/physical_asset.hpp" + +using namespace std; + +namespace mtconnect::asset { + using namespace entity; + + FactoryPtr PhysicalAsset::getMeasurementsFactory() + { + static FactoryPtr measurements; + + if (!measurements) + { + static auto measurement = make_shared(Requirements( + {Requirement("significantDigits", ValueType::INTEGER, false), + Requirement("units", false), Requirement("nativeUnits", false), + Requirement("code", false), Requirement("maximum", ValueType::DOUBLE, false), + Requirement("minimum", ValueType::DOUBLE, false), + Requirement("nominal", ValueType::DOUBLE, false), + Requirement("VALUE", ValueType::DOUBLE, false)})); + + measurements = make_shared(Requirements({Requirement( + "Measurement", ValueType::ENTITY, measurement, 1, Requirement::Infinite)})); + measurements->registerMatchers(); + measurements->registerFactory(regex(".+"), measurement); + } + return measurements; + } + + FactoryPtr PhysicalAsset::getFactory() + { + static FactoryPtr factory; + if (!factory) + { + static auto measurements = getMeasurementsFactory()->deepCopy(); + + factory = make_shared(*Asset::getFactory()); + factory->addRequirements(Requirements {{"ManufactureDate", ValueType::TIMESTAMP, false}, + {"CalibrationDate", ValueType::TIMESTAMP, false}, + {"InspectionDate", ValueType::TIMESTAMP, false}, + {"NextInspectionDate", ValueType::TIMESTAMP, false}, + {"Measurements", ValueType::ENTITY_LIST, measurements, false}}); + + auto meas = measurements->factoryFor("Measurement"); + meas->getRequirement("VALUE")->makeRequired(); + + factory->setOrder({"ManufactureDate", "CalibrationDate", "InspectionDate", "NextInspectionDate", "Measurements"}); + } + + return factory; + } + + void PhysicalAsset::registerAsset() + { + static bool once {true}; + if (once) + { + Asset::registerAssetType("PhysicalAsset", getFactory()); + once = false; + } + } + +} // namespace mtconnect::asset diff --git a/src/mtconnect/asset/physical_asset.hpp b/src/mtconnect/asset/physical_asset.hpp new file mode 100644 index 000000000..b55105dba --- /dev/null +++ b/src/mtconnect/asset/physical_asset.hpp @@ -0,0 +1,40 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include +#include +#include + +#include "asset.hpp" +#include "mtconnect/config.hpp" +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/entity/factory.hpp" +#include "mtconnect/utilities.hpp" + +namespace mtconnect::asset { + /// @brief abstract Physical Asset + class AGENT_LIB_API PhysicalAsset : public Asset + { + public: + static entity::FactoryPtr getFactory(); + static void registerAsset(); + static entity::FactoryPtr getMeasurementsFactory(); + + }; +} // namespace mtconnect::asset diff --git a/src/mtconnect/entity/xml_parser.cpp b/src/mtconnect/entity/xml_parser.cpp index 9c7a37f78..26d4b4cde 100644 --- a/src/mtconnect/entity/xml_parser.cpp +++ b/src/mtconnect/entity/xml_parser.cpp @@ -258,7 +258,7 @@ namespace mtconnect::entity { if (root != nullptr) entity = parseXmlNode(factory, root, errors, parseNamespaces); else - errors.emplace_back(new EntityError("Cannot parse asset")); + errors.emplace_back(new EntityError("Cannot parse document")); } catch (EntityError e) diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index 05427a32d..0527fcf0b 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -218,6 +218,7 @@ add_agent_test(qif_document TRUE asset) add_agent_test(asset_buffer TRUE asset) add_agent_test(component_parameters TRUE asset) add_agent_test(asset_hash TRUE asset) +add_agent_test(physical_asset FALSE asset) add_agent_test(agent_device TRUE device_model) add_agent_test(component FALSE device_model) diff --git a/test_package/physical_asset_test.cpp b/test_package/physical_asset_test.cpp new file mode 100644 index 000000000..dbfdf0dd7 --- /dev/null +++ b/test_package/physical_asset_test.cpp @@ -0,0 +1,234 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Ensure that gtest is the first header otherwise Windows raises an error +#include +// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) + +#include +#include +#include +#include +#include +#include +#include + +#include "agent_test_helper.hpp" +#include "json_helper.hpp" +#include "mtconnect/agent.hpp" +#include "mtconnect/asset/asset.hpp" +#include "mtconnect/asset/physical_asset.hpp" +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/entity/json_printer.hpp" +#include "mtconnect/entity/xml_parser.hpp" +#include "mtconnect/entity/xml_printer.hpp" +#include "mtconnect/printer//xml_printer.hpp" +#include "mtconnect/printer//xml_printer_helper.hpp" +#include "mtconnect/source/adapter/adapter.hpp" + +using json = nlohmann::json; +using namespace std; +using namespace mtconnect; +using namespace mtconnect::entity; +using namespace mtconnect::source::adapter; +using namespace mtconnect::asset; +using namespace mtconnect::printer; + +// main +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +class PhysicalAssetTest : public testing::Test +{ +protected: + void SetUp() override + { + PhysicalAsset::registerAsset(); + m_writer = make_unique(true); + } + + void TearDown() override + { + m_writer.reset(); + } + + std::unique_ptr m_writer; +}; + +TEST_F(PhysicalAssetTest, minimal_raw_material_definition) +{ + using namespace date; + const auto doc = R"DOC( + + 2022-05-20 + 2022-05-21 + 2022-05-22 + 2022-05-23 + + 5.1 + 1.27 + + +)DOC"; + + ErrorList errors; + entity::XmlParser parser; + + auto entity = parser.parse(Asset::getRoot(), doc, errors); + ASSERT_EQ(0, errors.size()); + + auto asset = dynamic_cast(entity.get()); + ASSERT_NE(nullptr, asset); + + ASSERT_EQ("7ae770f0-c11e-013a-c34c-4e7f553bbb76", asset->getAssetId()); + + ASSERT_FALSE(asset->getTimestamp()); + ASSERT_FALSE(asset->getDeviceUuid()); + + auto date = asset->get("ManufactureDate"); + auto ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(20, unsigned(ymd.day())); + + date = asset->get("CalibrationDate"); + ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(21, unsigned(ymd.day())); + + date = asset->get("InspectionDate"); + ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(22, unsigned(ymd.day())); + + date = asset->get("NextInspectionDate"); + ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(23, unsigned(ymd.day())); + + auto meas = asset->getList("Measurements"); + ASSERT_TRUE(meas); + ASSERT_EQ(2, meas->size()); + + auto it = meas->begin(); + ASSERT_EQ("Length", (*it)->getName()); + ASSERT_EQ("MILLIMETER", get((*it)->getProperty("units"))); + ASSERT_EQ(5.0, get((*it)->getProperty("nominal"))); + ASSERT_EQ(4.95, get((*it)->getProperty("minimum"))); + ASSERT_EQ(5.2, get((*it)->getProperty("maximum"))); + ASSERT_EQ(5.1, get((*it)->getProperty("VALUE"))); + + it++; + ASSERT_EQ("Diameter", (*it)->getName()); + ASSERT_EQ("MILLIMETER", get((*it)->getProperty("units"))); + ASSERT_EQ(1.25, get((*it)->getProperty("nominal"))); + ASSERT_EQ(0.95, get((*it)->getProperty("minimum"))); + ASSERT_EQ(1.4, get((*it)->getProperty("maximum"))); + ASSERT_EQ(1.27, get((*it)->getProperty("VALUE"))); +} + +TEST_F(PhysicalAssetTest, should_round_trip_xml) +{ + using namespace date; + const auto doc = + R"DOC( + 2022-05-20T00:00:00Z + 2022-05-21T00:00:00Z + 2022-05-22T00:00:00Z + 2022-05-23T00:00:00Z + + 5.1 + 1.27 + + +)DOC"; + + ErrorList errors; + entity::XmlParser parser; + + auto entity = parser.parse(Asset::getRoot(), doc, errors); + ASSERT_EQ(0, errors.size()); + + entity::XmlPrinter printer; + printer.print(*m_writer, entity, {"x"}); + string content = m_writer->getContent(); + + ASSERT_EQ(doc, content); +} + +TEST_F(PhysicalAssetTest, should_generate_json) +{ + using namespace date; + const auto doc = + R"DOC( + 2022-05-20T00:00:00Z + 2022-05-21T00:00:00Z + 2022-05-22T00:00:00Z + 2022-05-23T00:00:00Z + + 5.1 + 1.27 + + +)DOC"; + + ErrorList errors; + entity::XmlParser parser; + + auto entity = parser.parse(Asset::getRoot(), doc, errors); + ASSERT_EQ(0, errors.size()); + + entity::JsonEntityPrinter jsonPrinter(2, true); + auto json = jsonPrinter.print(entity); + + ASSERT_EQ(R"({ + "PhysicalAsset": { + "CalibrationDate": "2022-05-21T00:00:00Z", + "InspectionDate": "2022-05-22T00:00:00Z", + "ManufactureDate": "2022-05-20T00:00:00Z", + "Measurements": { + "Diameter": [ + { + "value": 1.27, + "maximum": 1.4, + "minimum": 0.95, + "nominal": 1.25, + "units": "MILLIMETER" + } + ], + "Length": [ + { + "value": 5.1, + "maximum": 5.2, + "minimum": 4.95, + "nominal": 5.0, + "units": "MILLIMETER" + } + ] + }, + "NextInspectionDate": "2022-05-23T00:00:00Z", + "assetId": "7ae770f0-c11e-013a-c34c-4e7f553bbb76" + } +})", + json); +} From 9d68909830725a95e8dd66083f0b7d3e168e8073 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 15 Jan 2025 17:14:19 -0500 Subject: [PATCH 126/128] Added pallet and fixture --- agent_lib/CMakeLists.txt | 4 + src/mtconnect/agent.cpp | 26 +- src/mtconnect/agent.hpp | 19 +- src/mtconnect/asset/cutting_tool.hpp | 2 +- src/mtconnect/asset/fixture.cpp | 54 ++++ src/mtconnect/asset/fixture.hpp | 37 +++ src/mtconnect/asset/pallet.cpp | 55 ++++ src/mtconnect/asset/pallet.hpp | 37 +++ src/mtconnect/asset/physical_asset.cpp | 40 +-- src/mtconnect/asset/physical_asset.hpp | 3 +- src/mtconnect/configuration/agent_config.cpp | 40 +-- src/mtconnect/configuration/agent_config.hpp | 47 +++- src/mtconnect/logging.hpp | 23 +- src/mtconnect/mqtt/mqtt_client_impl.hpp | 6 +- src/mtconnect/sink/mqtt_sink/mqtt_service.cpp | 4 +- src/mtconnect/sink/rest_sink/rest_service.cpp | 4 +- src/mtconnect/sink/sink.hpp | 9 +- .../validation/observation_validations.hpp | 190 ++++++++++--- src/mtconnect/validation/observations.hpp | 4 +- test_package/CMakeLists.txt | 2 + test_package/data_item_mapping_test.cpp | 34 +-- test_package/fixture_test.cpp | 251 +++++++++++++++++ test_package/json_mapping_test.cpp | 22 +- test_package/mqtt_sink_test.cpp | 14 +- test_package/observation_validation_test.cpp | 9 +- test_package/pallet_test.cpp | 256 ++++++++++++++++++ test_package/physical_asset_test.cpp | 37 ++- 27 files changed, 1035 insertions(+), 194 deletions(-) create mode 100644 src/mtconnect/asset/fixture.cpp create mode 100644 src/mtconnect/asset/fixture.hpp create mode 100644 src/mtconnect/asset/pallet.cpp create mode 100644 src/mtconnect/asset/pallet.hpp create mode 100644 test_package/fixture_test.cpp create mode 100644 test_package/pallet_test.cpp diff --git a/agent_lib/CMakeLists.txt b/agent_lib/CMakeLists.txt index e9340aa72..0943f4de6 100644 --- a/agent_lib/CMakeLists.txt +++ b/agent_lib/CMakeLists.txt @@ -26,6 +26,8 @@ set(AGENT_SOURCES "${SOURCE_DIR}/asset/qif_document.hpp" "${SOURCE_DIR}/asset/component_configuration_parameters.hpp" "${SOURCE_DIR}/asset/physical_asset.hpp" + "${SOURCE_DIR}/asset/fixture.hpp" + "${SOURCE_DIR}/asset/pallet.hpp" # src/asset SOURCE_FILES_ONLY @@ -36,6 +38,8 @@ set(AGENT_SOURCES "${SOURCE_DIR}/asset/qif_document.cpp" "${SOURCE_DIR}/asset/component_configuration_parameters.cpp" "${SOURCE_DIR}/asset/physical_asset.cpp" + "${SOURCE_DIR}/asset/fixture.cpp" + "${SOURCE_DIR}/asset/pallet.cpp" # src/buffer HEADER_FILES_ONLY diff --git a/src/mtconnect/agent.cpp b/src/mtconnect/agent.cpp index 2cdc88cdf..49182279c 100644 --- a/src/mtconnect/agent.cpp +++ b/src/mtconnect/agent.cpp @@ -46,6 +46,8 @@ #include "mtconnect/asset/component_configuration_parameters.hpp" #include "mtconnect/asset/cutting_tool.hpp" #include "mtconnect/asset/file_asset.hpp" +#include "mtconnect/asset/fixture.hpp" +#include "mtconnect/asset/pallet.hpp" #include "mtconnect/asset/qif_document.hpp" #include "mtconnect/asset/raw_material.hpp" #include "mtconnect/configuration/config_options.hpp" @@ -98,6 +100,8 @@ namespace mtconnect { RawMaterial::registerAsset(); QIFDocumentWrapper::registerAsset(); ComponentConfigurationParameters::registerAsset(); + Pallet::registerAsset(); + Fixture::registerAsset(); m_assetStorage = make_unique( GetOption(options, mtconnect::configuration::MaxAssets).value_or(1024)); @@ -242,7 +246,7 @@ namespace mtconnect { // Start all the sources for (auto source : m_sources) source->start(); - + m_afterStartHooks.exec(*this); } catch (std::runtime_error &e) @@ -478,11 +482,11 @@ namespace mtconnect { changed = receiveDevice(device, true) || changed; if (changed) { - if (source) - { - auto s = findSource(*source); - if (s) + if (source) { + auto s = findSource(*source); + if (s) + { s->setOptions({{config::Device, uuid}}); } } @@ -1018,7 +1022,7 @@ namespace mtconnect { if (m_agentDevice) { auto d = m_agentDevice->getDeviceDataItem("device_removed"); - if (d) + if (d) m_loopback->receive(d, oldUuid); } } @@ -1465,12 +1469,12 @@ namespace mtconnect { { try { - double fact_value = stod(factor); - double off_value = stod(offset); + double fact_value = stod(factor); + double off_value = stod(offset); - device_model::data_item::UnitConversion conv(fact_value, off_value); - di->setConverter(conv); - } + device_model::data_item::UnitConversion conv(fact_value, off_value); + di->setConverter(conv); + } catch (std::exception e) { LOG(error) << "Cannot convert factor " << factor << " or " << offset diff --git a/src/mtconnect/agent.hpp b/src/mtconnect/agent.hpp index de9f1a85d..3556d02b4 100644 --- a/src/mtconnect/agent.hpp +++ b/src/mtconnect/agent.hpp @@ -112,7 +112,7 @@ namespace mtconnect { /// @brief Hooks to run when before the agent starts all the soures and sinks /// @return configuration::HookManager& auto &beforeStartHooks() { return m_beforeStartHooks; } - + /// @brief Hooks to run when after the agent starts all the soures and sinks /// @return configuration::HookManager& auto &afterStartHooks() { return m_afterStartHooks; } @@ -663,7 +663,7 @@ namespace mtconnect { } buffer::CircularBuffer &getCircularBuffer() override { return m_agent->getCircularBuffer(); } - + configuration::HookManager &getHooks(HookType type) override { using namespace sink; @@ -672,7 +672,7 @@ namespace mtconnect { case BEFORE_START: return m_agent->beforeStartHooks(); break; - + case AFTER_START: return m_agent->afterStartHooks(); break; @@ -680,33 +680,32 @@ namespace mtconnect { case BEFORE_STOP: return m_agent->beforeStopHooks(); break; - + case BEFORE_DEVICE_XML_UPDATE: return m_agent->beforeDeviceXmlUpdateHooks(); break; - + case AFTER_DEVICE_XML_UPDATE: return m_agent->afterDeviceXmlUpdateHooks(); break; - + case BEFORE_INITIALIZE: return m_agent->beforeInitializeHooks(); break; - + case AFTER_INITIALIZE: return m_agent->afterInitializeHooks(); break; } - + LOG(error) << "getHooks: Bad hook manager type given to sink contract"; throw std::runtime_error("getHooks: Bad hook manager type"); - + // Never gets here. static configuration::HookManager NullHooks; return NullHooks; } - protected: Agent *m_agent; }; diff --git a/src/mtconnect/asset/cutting_tool.hpp b/src/mtconnect/asset/cutting_tool.hpp index 4af45f8d0..969a01270 100644 --- a/src/mtconnect/asset/cutting_tool.hpp +++ b/src/mtconnect/asset/cutting_tool.hpp @@ -22,9 +22,9 @@ #include #include "asset.hpp" +#include "mtconnect/asset/physical_asset.hpp" #include "mtconnect/config.hpp" #include "mtconnect/utilities.hpp" -#include "mtconnect/asset/physical_asset.hpp" namespace mtconnect { namespace asset { diff --git a/src/mtconnect/asset/fixture.cpp b/src/mtconnect/asset/fixture.cpp new file mode 100644 index 000000000..16bf509a8 --- /dev/null +++ b/src/mtconnect/asset/fixture.cpp @@ -0,0 +1,54 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "fixture.hpp" + +using namespace std; + +namespace mtconnect::asset { + using namespace entity; + + FactoryPtr Fixture::getFactory() + { + static FactoryPtr factory; + if (!factory) + { + factory = make_shared(*PhysicalAsset::getFactory()); + factory->addRequirements(Requirements {{"FixtureId", ValueType::STRING, false}, + {"FixtureNumber", ValueType::INTEGER, false}, + {"ClampingMethod", ValueType::STRING, false}, + {"MountingMethod", ValueType::STRING, false}}); + + factory->setOrder({"ManufactureDate", "CalibrationDate", "InspectionDate", + "NextInspectionDate", "Measurements", "FixtureId", "FixtureNumber", + "ClampingMethod", "MountingMethod"}); + } + + return factory; + } + + void Fixture::registerAsset() + { + static bool once {true}; + if (once) + { + Asset::registerAssetType("Fixture", getFactory()); + once = false; + } + } + +} // namespace mtconnect::asset diff --git a/src/mtconnect/asset/fixture.hpp b/src/mtconnect/asset/fixture.hpp new file mode 100644 index 000000000..5823f9432 --- /dev/null +++ b/src/mtconnect/asset/fixture.hpp @@ -0,0 +1,37 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include +#include +#include + +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/entity/factory.hpp" +#include "mtconnect/utilities.hpp" +#include "physical_asset.hpp" + +namespace mtconnect::asset { + /// @brief abstract Physical Asset + class AGENT_LIB_API Fixture : public PhysicalAsset + { + public: + static entity::FactoryPtr getFactory(); + static void registerAsset(); + }; +} // namespace mtconnect::asset diff --git a/src/mtconnect/asset/pallet.cpp b/src/mtconnect/asset/pallet.cpp new file mode 100644 index 000000000..1f3023620 --- /dev/null +++ b/src/mtconnect/asset/pallet.cpp @@ -0,0 +1,55 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "pallet.hpp" + +using namespace std; + +namespace mtconnect::asset { + using namespace entity; + + FactoryPtr Pallet::getFactory() + { + static FactoryPtr factory; + if (!factory) + { + factory = make_shared(*PhysicalAsset::getFactory()); + factory->addRequirements(Requirements {{"Type", ValueType::STRING, false}, + {"PalletId", ValueType::STRING, false}, + {"PalletNumber", ValueType::INTEGER, false}, + {"ClampingMethod", ValueType::STRING, false}, + {"MountingMethod", ValueType::STRING, false}}); + + factory->setOrder({"ManufactureDate", "CalibrationDate", "InspectionDate", + "NextInspectionDate", "Measurements", "Type", "PalletId", "PalletNumber", + "ClampingMethod", "MountingMethod"}); + } + + return factory; + } + + void Pallet::registerAsset() + { + static bool once {true}; + if (once) + { + Asset::registerAssetType("Pallet", getFactory()); + once = false; + } + } + +} // namespace mtconnect::asset diff --git a/src/mtconnect/asset/pallet.hpp b/src/mtconnect/asset/pallet.hpp new file mode 100644 index 000000000..77894aaf4 --- /dev/null +++ b/src/mtconnect/asset/pallet.hpp @@ -0,0 +1,37 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#pragma once + +#include +#include +#include + +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/entity/factory.hpp" +#include "mtconnect/utilities.hpp" +#include "physical_asset.hpp" + +namespace mtconnect::asset { + /// @brief abstract Physical Asset + class AGENT_LIB_API Pallet : public PhysicalAsset + { + public: + static entity::FactoryPtr getFactory(); + static void registerAsset(); + }; +} // namespace mtconnect::asset diff --git a/src/mtconnect/asset/physical_asset.cpp b/src/mtconnect/asset/physical_asset.cpp index c51b09bd7..c5e413d0b 100644 --- a/src/mtconnect/asset/physical_asset.cpp +++ b/src/mtconnect/asset/physical_asset.cpp @@ -25,43 +25,45 @@ namespace mtconnect::asset { FactoryPtr PhysicalAsset::getMeasurementsFactory() { static FactoryPtr measurements; - + if (!measurements) { static auto measurement = make_shared(Requirements( - {Requirement("significantDigits", ValueType::INTEGER, false), - Requirement("units", false), Requirement("nativeUnits", false), - Requirement("code", false), Requirement("maximum", ValueType::DOUBLE, false), - Requirement("minimum", ValueType::DOUBLE, false), - Requirement("nominal", ValueType::DOUBLE, false), - Requirement("VALUE", ValueType::DOUBLE, false)})); + {Requirement("significantDigits", ValueType::INTEGER, false), Requirement("units", false), + Requirement("nativeUnits", false), Requirement("code", false), + Requirement("maximum", ValueType::DOUBLE, false), + Requirement("minimum", ValueType::DOUBLE, false), + Requirement("nominal", ValueType::DOUBLE, false), + Requirement("VALUE", ValueType::DOUBLE, false)})); - measurements = make_shared(Requirements({Requirement( - "Measurement", ValueType::ENTITY, measurement, 1, Requirement::Infinite)})); - measurements->registerMatchers(); - measurements->registerFactory(regex(".+"), measurement); + measurements = make_shared(Requirements( + {Requirement("Measurement", ValueType::ENTITY, measurement, 1, Requirement::Infinite)})); + measurements->registerMatchers(); + measurements->registerFactory(regex(".+"), measurement); } return measurements; } - + FactoryPtr PhysicalAsset::getFactory() { static FactoryPtr factory; if (!factory) { static auto measurements = getMeasurementsFactory()->deepCopy(); - + factory = make_shared(*Asset::getFactory()); - factory->addRequirements(Requirements {{"ManufactureDate", ValueType::TIMESTAMP, false}, - {"CalibrationDate", ValueType::TIMESTAMP, false}, - {"InspectionDate", ValueType::TIMESTAMP, false}, - {"NextInspectionDate", ValueType::TIMESTAMP, false}, - {"Measurements", ValueType::ENTITY_LIST, measurements, false}}); + factory->addRequirements( + Requirements {{"ManufactureDate", ValueType::TIMESTAMP, false}, + {"CalibrationDate", ValueType::TIMESTAMP, false}, + {"InspectionDate", ValueType::TIMESTAMP, false}, + {"NextInspectionDate", ValueType::TIMESTAMP, false}, + {"Measurements", ValueType::ENTITY_LIST, measurements, false}}); auto meas = measurements->factoryFor("Measurement"); meas->getRequirement("VALUE")->makeRequired(); - factory->setOrder({"ManufactureDate", "CalibrationDate", "InspectionDate", "NextInspectionDate", "Measurements"}); + factory->setOrder({"ManufactureDate", "CalibrationDate", "InspectionDate", + "NextInspectionDate", "Measurements"}); } return factory; diff --git a/src/mtconnect/asset/physical_asset.hpp b/src/mtconnect/asset/physical_asset.hpp index b55105dba..216bc73ca 100644 --- a/src/mtconnect/asset/physical_asset.hpp +++ b/src/mtconnect/asset/physical_asset.hpp @@ -28,13 +28,12 @@ #include "mtconnect/utilities.hpp" namespace mtconnect::asset { - /// @brief abstract Physical Asset + /// @brief abstract Physical Asset class AGENT_LIB_API PhysicalAsset : public Asset { public: static entity::FactoryPtr getFactory(); static void registerAsset(); static entity::FactoryPtr getMeasurementsFactory(); - }; } // namespace mtconnect::asset diff --git a/src/mtconnect/configuration/agent_config.cpp b/src/mtconnect/configuration/agent_config.cpp index 8d9aae894..19b576fd1 100644 --- a/src/mtconnect/configuration/agent_config.cpp +++ b/src/mtconnect/configuration/agent_config.cpp @@ -430,7 +430,7 @@ namespace mtconnect::configuration { void AgentConfiguration::setLoggingLevel(const logr::trivial::severity_level level) { - for ( auto &[channelName, logChannel] : m_logChannels) + for (auto &[channelName, logChannel] : m_logChannels) logChannel.m_logLevel = level; } @@ -483,7 +483,7 @@ namespace mtconnect::configuration { logr::add_common_attributes(); core->add_global_attribute("Scope", logr::attributes::named_scope()); core->add_global_attribute(logr::aux::default_attribute_names::thread_id(), - logr::attributes::current_thread_id()); + logr::attributes::current_thread_id()); core->add_global_attribute("Timestamp", logr::attributes::utc_clock()); m_logger = &::boost::log::trivial::logger::get(); @@ -498,7 +498,9 @@ namespace mtconnect::configuration { configureLoggerChannel("agent", config, formatter); } - void AgentConfiguration::configureLoggerChannel(const std::string &channelName, const ptree &config, std::optional> formatter) + void AgentConfiguration::configureLoggerChannel( + const std::string &channelName, const ptree &config, + std::optional> formatter) { using namespace logr::trivial; namespace expr = logr::expressions; @@ -510,10 +512,10 @@ namespace mtconnect::configuration { if (!formatter) { - formatter = - expr::stream << expr::format_date_time("Timestamp", - "%Y-%m-%dT%H:%M:%S.%fZ ") - << std::setw(7) << std::left << boost::log::trivial::severity << " " << expr::message; + formatter = expr::stream << expr::format_date_time( + "Timestamp", "%Y-%m-%dT%H:%M:%S.%fZ ") + << std::setw(7) << std::left << boost::log::trivial::severity << " " + << expr::message; } ptree empty; @@ -553,11 +555,13 @@ namespace mtconnect::configuration { logChannel.m_logLevel = level; logChannel.m_logFileName = output.value_or("debug"); - sink->locked_backend()->add_stream(boost::shared_ptr(out, boost::null_deleter())); + sink->locked_backend()->add_stream( + boost::shared_ptr(out, boost::null_deleter())); sink->locked_backend()->auto_flush(true); sink->set_formatter(formatter.value()); - sink->set_filter(expr::attr("Channel") == logChannel.m_channelName && severity >= logChannel.m_logLevel); + sink->set_filter(expr::attr("Channel") == logChannel.m_channelName && + severity >= logChannel.m_logLevel); logr::core::get()->add_sink(sink); return; @@ -615,8 +619,7 @@ namespace mtconnect::configuration { logArchivePattern = fs::path(archive_pattern); if (!logArchivePattern.has_filename()) { - logArchivePattern = - logArchivePattern / archiveFileName(get(options["file_name"])); + logArchivePattern = logArchivePattern / archiveFileName(get(options["file_name"])); } if (logArchivePattern.is_relative()) @@ -648,16 +651,16 @@ namespace mtconnect::configuration { if (rotationLogInterval > 0) { - sink->locked_backend()->set_time_based_rotation( - logr::sinks::file::rotation_at_time_interval( - boost::posix_time::hours(rotationLogInterval))); + sink->locked_backend()->set_time_based_rotation(logr::sinks::file::rotation_at_time_interval( + boost::posix_time::hours(rotationLogInterval))); } // Upon restart, scan the target directory for files matching the file_name pattern sink->locked_backend()->scan_for_files(); sink->set_formatter(formatter.value()); - sink->set_filter(expr::attr("Channel") == logChannel.m_channelName && severity >= logChannel.m_logLevel); + sink->set_filter(expr::attr("Channel") == logChannel.m_channelName && + severity >= logChannel.m_logLevel); // Formatter for the logger logr::core::get()->add_sink(sink); @@ -949,7 +952,7 @@ namespace mtconnect::configuration { auto parsed = Url::parse(url); options[configuration::Protocol] = parsed.m_protocol; - + auto host = parsed.getHost(); if (host.empty()) { @@ -957,15 +960,14 @@ namespace mtconnect::configuration { exit(1); } options[configuration::Host] = host; - + if (parsed.m_port) options[configuration::Port] = parsed.getPort(); if (parsed.m_path != "/") { StringList list; string topics = parsed.m_path.substr(1, string::npos); - boost::split(list, topics, boost::is_any_of(":"), - boost::token_compress_on); + boost::split(list, topics, boost::is_any_of(":"), boost::token_compress_on); options[configuration::Topics] = list; } } diff --git a/src/mtconnect/configuration/agent_config.hpp b/src/mtconnect/configuration/agent_config.hpp index 071391472..eb0b51414 100644 --- a/src/mtconnect/configuration/agent_config.hpp +++ b/src/mtconnect/configuration/agent_config.hpp @@ -113,7 +113,9 @@ namespace mtconnect { /// @param channelName the log channel name /// @param config the configuration node /// @param formatter optional custom message format - void configureLoggerChannel(const std::string &channelName, const ptree &config, std::optional> formatter = std::nullopt); + void configureLoggerChannel( + const std::string &channelName, const ptree &config, + std::optional> formatter = std::nullopt); /// @brief Configure the agent logger with the config node from the config file /// @param config the configuration node @@ -155,22 +157,40 @@ namespace mtconnect { ///@{ /// @brief gets the boost log sink /// @return boost log sink - const auto &getLoggerSink(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logSink; } + const auto &getLoggerSink(const std::string &channelName = "agent") + { + return m_logChannels[channelName].m_logSink; + } /// @brief gets the log directory /// @return log directory - const auto &getLogDirectory(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logDirectory; } + const auto &getLogDirectory(const std::string &channelName = "agent") + { + return m_logChannels[channelName].m_logDirectory; + } /// @brief get the logging file name /// @return log file name - const auto &getLogFileName(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logFileName; } + const auto &getLogFileName(const std::string &channelName = "agent") + { + return m_logChannels[channelName].m_logFileName; + } /// @brief for log rolling, get the log archive pattern /// @return log archive pattern - const auto &getLogArchivePattern(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logArchivePattern; } + const auto &getLogArchivePattern(const std::string &channelName = "agent") + { + return m_logChannels[channelName].m_logArchivePattern; + } /// @brief Get the maximum size of all the log files /// @return the maximum size of all log files - auto getMaxLogFileSize(const std::string &channelName = "agent") { return m_logChannels[channelName].m_maxLogFileSize; } + auto getMaxLogFileSize(const std::string &channelName = "agent") + { + return m_logChannels[channelName].m_maxLogFileSize; + } /// @brief the maximum size of a log file when it triggers rolling over /// @return the maxumum site of a log file - auto getLogRotationSize(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logRotationSize; } + auto getLogRotationSize(const std::string &channelName = "agent") + { + return m_logChannels[channelName].m_logRotationSize; + } /// @brief How often to roll over the log file /// /// One of: @@ -179,10 +199,16 @@ namespace mtconnect { /// - `NEVER` /// /// @return the log file interval - auto getRotationLogInterval(const std::string &channelName = "agent") { return m_logChannels[channelName].m_rotationLogInterval; } + auto getRotationLogInterval(const std::string &channelName = "agent") + { + return m_logChannels[channelName].m_rotationLogInterval; + } /// @brief Get the current log level /// @return log level - auto getLogLevel(const std::string &channelName = "agent") { return m_logChannels[channelName].m_logLevel; } + auto getLogLevel(const std::string &channelName = "agent") + { + return m_logChannels[channelName].m_logLevel; + } /// @brief set the logging level /// @param[in] level the new logging level @@ -311,7 +337,8 @@ namespace mtconnect { protected: using text_sink = boost::log::sinks::synchronous_sink; - using console_sink = boost::log::sinks::synchronous_sink; + using console_sink = + boost::log::sinks::synchronous_sink; struct LogChannel { diff --git a/src/mtconnect/logging.hpp b/src/mtconnect/logging.hpp index c0e1f9f73..7f7ac3714 100644 --- a/src/mtconnect/logging.hpp +++ b/src/mtconnect/logging.hpp @@ -21,21 +21,23 @@ #pragma once #include -#include -#include #include +#include +#include #include "mtconnect/config.hpp" -typedef boost::log::sources::severity_channel_logger_mt -< - boost::log::trivial::severity_level, // the type of the severity level - std::string // the type of the channel name -> channel_logger_mt; +typedef boost::log::sources::severity_channel_logger_mt< + boost::log::trivial::severity_level, // the type of the severity level + std::string // the type of the channel name + > + channel_logger_mt; -#define CHANNEL_LOGGER_INIT(logger, channelName) \ -BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(logger, channel_logger_mt) \ -{ return channel_logger_mt(boost::log::keywords::channel = channelName); } +#define CHANNEL_LOGGER_INIT(logger, channelName) \ + BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(logger, channel_logger_mt) \ + { \ + return channel_logger_mt(boost::log::keywords::channel = channelName); \ + } CHANNEL_LOGGER_INIT(agent_logger, "agent") @@ -45,4 +47,3 @@ CHANNEL_LOGGER_INIT(agent_logger, "agent") #define NAMED_SCOPE BOOST_LOG_NAMED_SCOPE #define LOG_LEVEL(lvl) ::boost::log::trivial::lvl - diff --git a/src/mtconnect/mqtt/mqtt_client_impl.hpp b/src/mtconnect/mqtt/mqtt_client_impl.hpp index 7b7155e50..850387b89 100644 --- a/src/mtconnect/mqtt/mqtt_client_impl.hpp +++ b/src/mtconnect/mqtt/mqtt_client_impl.hpp @@ -476,7 +476,7 @@ namespace mtconnect { { return static_pointer_cast(shared_from_this()); } - + /// @brief Get the Mqtt TCP Client /// @return pointer to the Mqtt TCP Client auto &getClient() @@ -558,7 +558,7 @@ namespace mtconnect { { return static_pointer_cast(shared_from_this()); } - + /// @brief Get the Mqtt TLS WebSocket Client /// @return pointer to the Mqtt TLS WebSocket Client auto &getClient() @@ -597,7 +597,7 @@ namespace mtconnect { { return static_pointer_cast(shared_from_this()); } - + /// @brief Get the Mqtt TLS WebSocket Client /// @return pointer to the Mqtt TLS WebSocket Client auto &getClient() diff --git a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp index 72fbfd6e4..4d8fa5261 100644 --- a/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp +++ b/src/mtconnect/sink/mqtt_sink/mqtt_service.cpp @@ -289,8 +289,8 @@ namespace mtconnect { m_currentTimer.expires_after(m_currentInterval); m_currentTimer.async_wait(boost::asio::bind_executor( m_strand, boost::bind(&MqttService::publishCurrent, this, _1))); - - return seq; + + return seq; } bool MqttService::publish(observation::ObservationPtr &observation) diff --git a/src/mtconnect/sink/rest_sink/rest_service.cpp b/src/mtconnect/sink/rest_sink/rest_service.cpp index 86a859f3c..f4b9bea7a 100644 --- a/src/mtconnect/sink/rest_sink/rest_service.cpp +++ b/src/mtconnect/sink/rest_sink/rest_service.cpp @@ -550,13 +550,13 @@ namespace mtconnect { auto format = request->parameter("format"); auto pretty = request->parameter("pretty").value_or(false); auto printer = getPrinter(request->m_accepts, format); - + list ids; stringstream str(*asset); string id; while (getline(str, id, ';')) ids.emplace_back(id); - + respond(session, assetIdsRequest(printer, ids, pretty, request->m_requestId), request->m_requestId); } diff --git a/src/mtconnect/sink/sink.hpp b/src/mtconnect/sink/sink.hpp index 4678cde16..416564933 100644 --- a/src/mtconnect/sink/sink.hpp +++ b/src/mtconnect/sink/sink.hpp @@ -28,10 +28,10 @@ #include "mtconnect/asset/asset_storage.hpp" #include "mtconnect/buffer/circular_buffer.hpp" #include "mtconnect/config.hpp" +#include "mtconnect/configuration/hook_manager.hpp" #include "mtconnect/device_model/device.hpp" #include "mtconnect/observation/observation.hpp" #include "mtconnect/printer//printer.hpp" -#include "mtconnect/configuration/hook_manager.hpp" namespace mtconnect { namespace printer { @@ -55,7 +55,8 @@ namespace mtconnect { class AGENT_LIB_API SinkContract { public: - enum HookType { + enum HookType + { BEFORE_STOP, BEFORE_START, AFTER_START, @@ -64,7 +65,7 @@ namespace mtconnect { BEFORE_INITIALIZE, AFTER_INITIALIZE }; - + virtual ~SinkContract() = default; /// @brief get the printer for a mime type. Current options: `xml` or `json`. /// @param[in] aType a string for the type @@ -114,7 +115,7 @@ namespace mtconnect { /// @brief Get a pointer to the asset storage /// @return a pointer to the asset storage. virtual const asset::AssetStorage *getAssetStorage() = 0; - + /// @brief Get a reference to the hook manager for the agent. /// @param[in] type the type manager to retrieve /// @return a reference to the hook manager diff --git a/src/mtconnect/validation/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index 0fbb4b078..1c19ba4fa 100644 --- a/src/mtconnect/validation/observation_validations.hpp +++ b/src/mtconnect/validation/observation_validations.hpp @@ -1,32 +1,77 @@ Validation ControlledVocabularies { {"ActiveAxes", {}}, - {"ActuatorState", {{"ACTIVE", { SCHEMA_VERSION(1, 2), 0} }, {"INACTIVE", { SCHEMA_VERSION(1, 2), 0} }}}, + {"ActuatorState", + {{"ACTIVE", {SCHEMA_VERSION(1, 2), 0}}, {"INACTIVE", {SCHEMA_VERSION(1, 2), 0}}}}, {"Alarm", {}}, {"AssetChanged", {}}, {"AssetRemoved", {}}, - {"Availability", {{"AVAILABLE", { SCHEMA_VERSION(1, 1), 0} }, {"UNAVAILABLE", { SCHEMA_VERSION(1, 1), 0} }}}, - {"AxisCoupling", {{"MASTER", { SCHEMA_VERSION(1, 1), 0} }, {"SLAVE", { SCHEMA_VERSION(1, 1), 0} }, {"SYNCHRONOUS", { SCHEMA_VERSION(1, 1), 0} }, {"TANDEM", { SCHEMA_VERSION(1, 1), 0} }}}, + {"Availability", + {{"AVAILABLE", {SCHEMA_VERSION(1, 1), 0}}, {"UNAVAILABLE", {SCHEMA_VERSION(1, 1), 0}}}}, + {"AxisCoupling", + {{"MASTER", {SCHEMA_VERSION(1, 1), 0}}, + {"SLAVE", {SCHEMA_VERSION(1, 1), 0}}, + {"SYNCHRONOUS", {SCHEMA_VERSION(1, 1), 0}}, + {"TANDEM", {SCHEMA_VERSION(1, 1), 0}}}}, {"AxisFeedrateOverride", {}}, - {"AxisInterlock", {{"ACTIVE", { SCHEMA_VERSION(1, 3), 0} }, {"INACTIVE", { SCHEMA_VERSION(1, 3), 0} }}}, - {"AxisState", {{"HOME", { SCHEMA_VERSION(1, 3), 0} }, {"PARKED", { SCHEMA_VERSION(1, 3), 0} }, {"STOPPED", { SCHEMA_VERSION(1, 3), 0} }, {"TRAVEL", { SCHEMA_VERSION(1, 3), 0} }}}, + {"AxisInterlock", + {{"ACTIVE", {SCHEMA_VERSION(1, 3), 0}}, {"INACTIVE", {SCHEMA_VERSION(1, 3), 0}}}}, + {"AxisState", + {{"HOME", {SCHEMA_VERSION(1, 3), 0}}, + {"PARKED", {SCHEMA_VERSION(1, 3), 0}}, + {"STOPPED", {SCHEMA_VERSION(1, 3), 0}}, + {"TRAVEL", {SCHEMA_VERSION(1, 3), 0}}}}, {"Block", {}}, {"BlockCount", {}}, - {"ChuckInterlock", {{"ACTIVE", { SCHEMA_VERSION(1, 3), 0} }, {"INACTIVE", { SCHEMA_VERSION(1, 3), 0} }}}, - {"ChuckState", {{"CLOSED", { SCHEMA_VERSION(1, 3), 0} }, {"OPEN", { SCHEMA_VERSION(1, 3), 0} }, {"UNLATCHED", { SCHEMA_VERSION(1, 3), 0} }}}, + {"ChuckInterlock", + {{"ACTIVE", {SCHEMA_VERSION(1, 3), 0}}, {"INACTIVE", {SCHEMA_VERSION(1, 3), 0}}}}, + {"ChuckState", + {{"CLOSED", {SCHEMA_VERSION(1, 3), 0}}, + {"OPEN", {SCHEMA_VERSION(1, 3), 0}}, + {"UNLATCHED", {SCHEMA_VERSION(1, 3), 0}}}}, {"Code", {}}, {"CompositionState", {}}, - {"ControllerMode", {{"AUTOMATIC", { SCHEMA_VERSION(1, 0), 0} }, {"MANUAL", { SCHEMA_VERSION(1, 0), 0} }, {"MANUAL_DATA_INPUT", { SCHEMA_VERSION(1, 0), 0} }, {"SEMI_AUTOMATIC", { SCHEMA_VERSION(1, 1), 0} }, {"FEED_HOLD", { SCHEMA_VERSION(1, 2), SCHEMA_VERSION(1, 3)} }, {"EDIT", { SCHEMA_VERSION(1, 3), 0} }}}, - {"ControllerModeOverride", {{"OFF", { SCHEMA_VERSION(1, 4), 0} }, {"ON", { SCHEMA_VERSION(1, 4), 0} }}}, + {"ControllerMode", + {{"AUTOMATIC", {SCHEMA_VERSION(1, 0), 0}}, + {"MANUAL", {SCHEMA_VERSION(1, 0), 0}}, + {"MANUAL_DATA_INPUT", {SCHEMA_VERSION(1, 0), 0}}, + {"SEMI_AUTOMATIC", {SCHEMA_VERSION(1, 1), 0}}, + {"FEED_HOLD", {SCHEMA_VERSION(1, 2), SCHEMA_VERSION(1, 3)}}, + {"EDIT", {SCHEMA_VERSION(1, 3), 0}}}}, + {"ControllerModeOverride", + {{"OFF", {SCHEMA_VERSION(1, 4), 0}}, {"ON", {SCHEMA_VERSION(1, 4), 0}}}}, {"CoupledAxes", {}}, {"DateCode", {}}, {"DeviceUuid", {}}, - {"Direction", {{"CLOCKWISE", { SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 4)} }, {"COUNTER_CLOCKWISE", { SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 4)} }, {"NEGATIVE", { SCHEMA_VERSION(1, 2), SCHEMA_VERSION(1, 4)} }, {"POSITIVE", { SCHEMA_VERSION(1, 2), SCHEMA_VERSION(1, 4)} }}}, - {"DoorState", {{"CLOSED", { SCHEMA_VERSION(1, 1), 0} }, {"OPEN", { SCHEMA_VERSION(1, 1), 0} }, {"UNLATCHED", { SCHEMA_VERSION(1, 2), 0} }}}, - {"EmergencyStop", {{"ARMED", { SCHEMA_VERSION(1, 1), 0} }, {"TRIGGERED", { SCHEMA_VERSION(1, 1), 0} }}}, - {"EndOfBar", {{"NO", { SCHEMA_VERSION(1, 3), 0} }, {"YES", { SCHEMA_VERSION(1, 3), 0} }}}, - {"EquipmentMode", {{"OFF", { SCHEMA_VERSION(1, 4), 0} }, {"ON", { SCHEMA_VERSION(1, 4), 0} }}}, - {"Execution", {{"ACTIVE", { SCHEMA_VERSION(1, 0), 0} }, {"INTERRUPTED", { SCHEMA_VERSION(1, 0), 0} }, {"READY", { SCHEMA_VERSION(1, 0), 0} }, {"STOPPED", { SCHEMA_VERSION(1, 0), 0} }, {"FEED_HOLD", { SCHEMA_VERSION(1, 3), 0} }, {"PROGRAM_COMPLETED", { SCHEMA_VERSION(1, 3), 0} }, {"PROGRAM_OPTIONAL_STOP", { SCHEMA_VERSION(1, 3), SCHEMA_VERSION(1, 4)} }, {"PROGRAM_STOPPED", { SCHEMA_VERSION(1, 3), 0} }, {"OPTIONAL_STOP", { SCHEMA_VERSION(1, 4), 0} }, {"WAIT", { SCHEMA_VERSION(1, 5), 0} }}}, - {"FunctionalMode", {{"MAINTENANCE", { SCHEMA_VERSION(1, 3), 0} }, {"PROCESS_DEVELOPMENT", { SCHEMA_VERSION(1, 3), 0} }, {"PRODUCTION", { SCHEMA_VERSION(1, 3), 0} }, {"SETUP", { SCHEMA_VERSION(1, 3), 0} }, {"TEARDOWN", { SCHEMA_VERSION(1, 3), 0} }}}, + {"Direction", + {{"CLOCKWISE", {SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 4)}}, + {"COUNTER_CLOCKWISE", {SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 4)}}, + {"NEGATIVE", {SCHEMA_VERSION(1, 2), SCHEMA_VERSION(1, 4)}}, + {"POSITIVE", {SCHEMA_VERSION(1, 2), SCHEMA_VERSION(1, 4)}}}}, + {"DoorState", + {{"CLOSED", {SCHEMA_VERSION(1, 1), 0}}, + {"OPEN", {SCHEMA_VERSION(1, 1), 0}}, + {"UNLATCHED", {SCHEMA_VERSION(1, 2), 0}}}}, + {"EmergencyStop", + {{"ARMED", {SCHEMA_VERSION(1, 1), 0}}, {"TRIGGERED", {SCHEMA_VERSION(1, 1), 0}}}}, + {"EndOfBar", {{"NO", {SCHEMA_VERSION(1, 3), 0}}, {"YES", {SCHEMA_VERSION(1, 3), 0}}}}, + {"EquipmentMode", {{"OFF", {SCHEMA_VERSION(1, 4), 0}}, {"ON", {SCHEMA_VERSION(1, 4), 0}}}}, + {"Execution", + {{"ACTIVE", {SCHEMA_VERSION(1, 0), 0}}, + {"INTERRUPTED", {SCHEMA_VERSION(1, 0), 0}}, + {"READY", {SCHEMA_VERSION(1, 0), 0}}, + {"STOPPED", {SCHEMA_VERSION(1, 0), 0}}, + {"FEED_HOLD", {SCHEMA_VERSION(1, 3), 0}}, + {"PROGRAM_COMPLETED", {SCHEMA_VERSION(1, 3), 0}}, + {"PROGRAM_OPTIONAL_STOP", {SCHEMA_VERSION(1, 3), SCHEMA_VERSION(1, 4)}}, + {"PROGRAM_STOPPED", {SCHEMA_VERSION(1, 3), 0}}, + {"OPTIONAL_STOP", {SCHEMA_VERSION(1, 4), 0}}, + {"WAIT", {SCHEMA_VERSION(1, 5), 0}}}}, + {"FunctionalMode", + {{"MAINTENANCE", {SCHEMA_VERSION(1, 3), 0}}, + {"PROCESS_DEVELOPMENT", {SCHEMA_VERSION(1, 3), 0}}, + {"PRODUCTION", {SCHEMA_VERSION(1, 3), 0}}, + {"SETUP", {SCHEMA_VERSION(1, 3), 0}}, + {"TEARDOWN", {SCHEMA_VERSION(1, 3), 0}}}}, {"Hardness", {}}, {"Line", {}}, {"LineLabel", {}}, @@ -37,26 +82,41 @@ Validation ControlledVocabularies { {"OperatorId", {}}, {"PalletId", {}}, {"PartCount", {}}, - {"PartDetect", {{"NOT_PRESENT", { SCHEMA_VERSION(1, 5), 0} }, {"PRESENT", { SCHEMA_VERSION(1, 5), 0} }}}, + {"PartDetect", + {{"NOT_PRESENT", {SCHEMA_VERSION(1, 5), 0}}, {"PRESENT", {SCHEMA_VERSION(1, 5), 0}}}}, {"PartId", {}}, {"PartNumber", {}}, {"PathFeedrateOverride", {}}, - {"PathMode", {{"INDEPENDENT", { SCHEMA_VERSION(1, 1), 0} }, {"MIRROR", { SCHEMA_VERSION(1, 1), 0} }, {"SYNCHRONOUS", { SCHEMA_VERSION(1, 1), 0} }, {"MASTER", { SCHEMA_VERSION(1, 2), 0} }}}, - {"PowerState", {{"OFF", { SCHEMA_VERSION(1, 1), 0} }, {"ON", { SCHEMA_VERSION(1, 1), 0} }}}, - {"PowerStatus", {{"OFF", { SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 1)} }, {"ON", { SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 1)} }}}, + {"PathMode", + {{"INDEPENDENT", {SCHEMA_VERSION(1, 1), 0}}, + {"MIRROR", {SCHEMA_VERSION(1, 1), 0}}, + {"SYNCHRONOUS", {SCHEMA_VERSION(1, 1), 0}}, + {"MASTER", {SCHEMA_VERSION(1, 2), 0}}}}, + {"PowerState", {{"OFF", {SCHEMA_VERSION(1, 1), 0}}, {"ON", {SCHEMA_VERSION(1, 1), 0}}}}, + {"PowerStatus", + {{"OFF", {SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 1)}}, + {"ON", {SCHEMA_VERSION(1, 0), SCHEMA_VERSION(1, 1)}}}}, {"ProcessTime", {}}, {"Program", {}}, {"ProgramComment", {}}, - {"ProgramEdit", {{"ACTIVE", { SCHEMA_VERSION(1, 3), 0} }, {"NOT_READY", { SCHEMA_VERSION(1, 3), 0} }, {"READY", { SCHEMA_VERSION(1, 3), 0} }}}, + {"ProgramEdit", + {{"ACTIVE", {SCHEMA_VERSION(1, 3), 0}}, + {"NOT_READY", {SCHEMA_VERSION(1, 3), 0}}, + {"READY", {SCHEMA_VERSION(1, 3), 0}}}}, {"ProgramEditName", {}}, {"ProgramHeader", {}}, {"ProgramLocation", {}}, - {"ProgramLocationType", {{"EXTERNAL", { SCHEMA_VERSION(1, 5), 0} }, {"LOCAL", { SCHEMA_VERSION(1, 5), 0} }}}, + {"ProgramLocationType", + {{"EXTERNAL", {SCHEMA_VERSION(1, 5), 0}}, {"LOCAL", {SCHEMA_VERSION(1, 5), 0}}}}, {"ProgramNestLevel", {}}, - {"RotaryMode", {{"CONTOUR", { SCHEMA_VERSION(1, 1), 0} }, {"INDEX", { SCHEMA_VERSION(1, 1), 0} }, {"SPINDLE", { SCHEMA_VERSION(1, 1), 0} }}}, + {"RotaryMode", + {{"CONTOUR", {SCHEMA_VERSION(1, 1), 0}}, + {"INDEX", {SCHEMA_VERSION(1, 1), 0}}, + {"SPINDLE", {SCHEMA_VERSION(1, 1), 0}}}}, {"RotaryVelocityOverride", {}}, {"SerialNumber", {}}, - {"SpindleInterlock", {{"ACTIVE", { SCHEMA_VERSION(1, 3), 0} }, {"INACTIVE", { SCHEMA_VERSION(1, 3), 0} }}}, + {"SpindleInterlock", + {{"ACTIVE", {SCHEMA_VERSION(1, 3), 0}}, {"INACTIVE", {SCHEMA_VERSION(1, 3), 0}}}}, {"ToolAssetId", {}}, {"ToolGroup", {}}, {"ToolId", {}}, @@ -64,7 +124,18 @@ Validation ControlledVocabularies { {"ToolOffset", {}}, {"User", {}}, {"Variable", {}}, - {"WaitState", {{"MATERIAL_LOAD", { SCHEMA_VERSION(1, 5), 0} }, {"MATERIAL_UNLOAD", { SCHEMA_VERSION(1, 5), 0} }, {"PART_LOAD", { SCHEMA_VERSION(1, 5), 0} }, {"PART_UNLOAD", { SCHEMA_VERSION(1, 5), 0} }, {"PAUSING", { SCHEMA_VERSION(1, 5), 0} }, {"POWERING_DOWN", { SCHEMA_VERSION(1, 5), 0} }, {"POWERING_UP", { SCHEMA_VERSION(1, 5), 0} }, {"RESUMING", { SCHEMA_VERSION(1, 5), 0} }, {"SECONDARY_PROCESS", { SCHEMA_VERSION(1, 5), 0} }, {"TOOL_LOAD", { SCHEMA_VERSION(1, 5), 0} }, {"TOOL_UNLOAD", { SCHEMA_VERSION(1, 5), 0} }}}, + {"WaitState", + {{"MATERIAL_LOAD", {SCHEMA_VERSION(1, 5), 0}}, + {"MATERIAL_UNLOAD", {SCHEMA_VERSION(1, 5), 0}}, + {"PART_LOAD", {SCHEMA_VERSION(1, 5), 0}}, + {"PART_UNLOAD", {SCHEMA_VERSION(1, 5), 0}}, + {"PAUSING", {SCHEMA_VERSION(1, 5), 0}}, + {"POWERING_DOWN", {SCHEMA_VERSION(1, 5), 0}}, + {"POWERING_UP", {SCHEMA_VERSION(1, 5), 0}}, + {"RESUMING", {SCHEMA_VERSION(1, 5), 0}}, + {"SECONDARY_PROCESS", {SCHEMA_VERSION(1, 5), 0}}, + {"TOOL_LOAD", {SCHEMA_VERSION(1, 5), 0}}, + {"TOOL_UNLOAD", {SCHEMA_VERSION(1, 5), 0}}}}, {"Wire", {}}, {"WorkholdingId", {}}, {"WorkOffset", {}}, @@ -77,7 +148,7 @@ Validation ControlledVocabularies { {"Rotation", {}}, {"Translation", {}}, {"ProcessKindId", {}}, - {"PartStatus", {{"FAIL", { SCHEMA_VERSION(1, 7), 0} }, {"PASS", { SCHEMA_VERSION(1, 7), 0} }}}, + {"PartStatus", {{"FAIL", {SCHEMA_VERSION(1, 7), 0}}, {"PASS", {SCHEMA_VERSION(1, 7), 0}}}}, {"AlarmLimit", {}}, {"ProcessAggregateId", {}}, {"PartKindId", {}}, @@ -85,7 +156,10 @@ Validation ControlledVocabularies { {"DeviceRemoved", {}}, {"DeviceChanged", {}}, {"SpecificationLimit", {}}, - {"ConnectionStatus", {{"CLOSED", { SCHEMA_VERSION(1, 7), 0} }, {"ESTABLISHED", { SCHEMA_VERSION(1, 7), 0} }, {"LISTEN", { SCHEMA_VERSION(1, 7), 0} }}}, + {"ConnectionStatus", + {{"CLOSED", {SCHEMA_VERSION(1, 7), 0}}, + {"ESTABLISHED", {SCHEMA_VERSION(1, 7), 0}}, + {"LISTEN", {SCHEMA_VERSION(1, 7), 0}}}}, {"AdapterSoftwareVersion", {}}, {"SensorAttachment", {}}, {"ControlLimit", {}}, @@ -98,22 +172,52 @@ Validation ControlledVocabularies { {"DeactivationCount", {}}, {"TransferCount", {}}, {"LoadCount", {}}, - {"PartProcessingState", {{"IN_PROCESS", { SCHEMA_VERSION(1, 8), 0} }, {"IN_TRANSIT", { SCHEMA_VERSION(1, 8), 0} }, {"NEEDS_PROCESSING", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_ABORTED", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_COMPLETE", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_LOST", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_REJECTED", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_SKIPPED", { SCHEMA_VERSION(1, 8), 0} }, {"PROCESSING_ENDED_STOPPED", { SCHEMA_VERSION(1, 8), 0} }, {"TRANSIT_COMPLETE", { SCHEMA_VERSION(1, 8), 0} }, {"WAITING_FOR_TRANSIT", { SCHEMA_VERSION(1, 8), 0} }}}, - {"ProcessState", {{"ABORTED", { SCHEMA_VERSION(1, 8), 0} }, {"ACTIVE", { SCHEMA_VERSION(1, 8), 0} }, {"COMPLETE", { SCHEMA_VERSION(1, 8), 0} }, {"INITIALIZING", { SCHEMA_VERSION(1, 8), 0} }, {"INTERRUPTED", { SCHEMA_VERSION(1, 8), 0} }, {"READY", { SCHEMA_VERSION(1, 8), 0} }}}, - {"ValveState", {{"CLOSED", { SCHEMA_VERSION(1, 8), 0} }, {"CLOSING", { SCHEMA_VERSION(1, 8), 0} }, {"OPEN", { SCHEMA_VERSION(1, 8), 0} }, {"OPENING", { SCHEMA_VERSION(1, 8), 0} }}}, - {"LockState", {{"LOCKED", { SCHEMA_VERSION(1, 8), 0} }, {"UNLOCKED", { SCHEMA_VERSION(1, 8), 0} }}}, + {"PartProcessingState", + {{"IN_PROCESS", {SCHEMA_VERSION(1, 8), 0}}, + {"IN_TRANSIT", {SCHEMA_VERSION(1, 8), 0}}, + {"NEEDS_PROCESSING", {SCHEMA_VERSION(1, 8), 0}}, + {"PROCESSING_ENDED", {SCHEMA_VERSION(1, 8), 0}}, + {"PROCESSING_ENDED_ABORTED", {SCHEMA_VERSION(1, 8), 0}}, + {"PROCESSING_ENDED_COMPLETE", {SCHEMA_VERSION(1, 8), 0}}, + {"PROCESSING_ENDED_LOST", {SCHEMA_VERSION(1, 8), 0}}, + {"PROCESSING_ENDED_REJECTED", {SCHEMA_VERSION(1, 8), 0}}, + {"PROCESSING_ENDED_SKIPPED", {SCHEMA_VERSION(1, 8), 0}}, + {"PROCESSING_ENDED_STOPPED", {SCHEMA_VERSION(1, 8), 0}}, + {"TRANSIT_COMPLETE", {SCHEMA_VERSION(1, 8), 0}}, + {"WAITING_FOR_TRANSIT", {SCHEMA_VERSION(1, 8), 0}}}}, + {"ProcessState", + {{"ABORTED", {SCHEMA_VERSION(1, 8), 0}}, + {"ACTIVE", {SCHEMA_VERSION(1, 8), 0}}, + {"COMPLETE", {SCHEMA_VERSION(1, 8), 0}}, + {"INITIALIZING", {SCHEMA_VERSION(1, 8), 0}}, + {"INTERRUPTED", {SCHEMA_VERSION(1, 8), 0}}, + {"READY", {SCHEMA_VERSION(1, 8), 0}}}}, + {"ValveState", + {{"CLOSED", {SCHEMA_VERSION(1, 8), 0}}, + {"CLOSING", {SCHEMA_VERSION(1, 8), 0}}, + {"OPEN", {SCHEMA_VERSION(1, 8), 0}}, + {"OPENING", {SCHEMA_VERSION(1, 8), 0}}}}, + {"LockState", {{"LOCKED", {SCHEMA_VERSION(1, 8), 0}}, {"UNLOCKED", {SCHEMA_VERSION(1, 8), 0}}}}, {"UnloadCount", {}}, {"CycleCount", {}}, - {"OperatingMode", {{"AUTOMATIC", { SCHEMA_VERSION(2, 0), 0} }, {"MANUAL", { SCHEMA_VERSION(2, 0), 0} }, {"SEMI_AUTOMATIC", { SCHEMA_VERSION(2, 0), 0} }}}, + {"OperatingMode", + {{"AUTOMATIC", {SCHEMA_VERSION(2, 0), 0}}, + {"MANUAL", {SCHEMA_VERSION(2, 0), 0}}, + {"SEMI_AUTOMATIC", {SCHEMA_VERSION(2, 0), 0}}}}, {"AssetCount", {}}, {"MaintenanceList", {}}, {"FixtureId", {}}, - {"PartCountType", {{"BATCH", { SCHEMA_VERSION(2, 0), 0} }, {"EACH", { SCHEMA_VERSION(2, 0), 0} }}}, + {"PartCountType", {{"BATCH", {SCHEMA_VERSION(2, 0), 0}}, {"EACH", {SCHEMA_VERSION(2, 0), 0}}}}, {"ClockTime", {}}, {"NetworkPort", {}}, {"HostName", {}}, - {"LeakDetect", {{"DETECTED", { SCHEMA_VERSION(2, 1), 0} }, {"NOT_DETECTED", { SCHEMA_VERSION(2, 1), 0} }}}, - {"BatteryState", {{"CHARGED", { SCHEMA_VERSION(2, 1), 0} }, {"CHARGING", { SCHEMA_VERSION(2, 1), 0} }, {"DISCHARGED", { SCHEMA_VERSION(2, 1), 0} }, {"DISCHARGING", { SCHEMA_VERSION(2, 1), 0} }}}, + {"LeakDetect", + {{"DETECTED", {SCHEMA_VERSION(2, 1), 0}}, {"NOT_DETECTED", {SCHEMA_VERSION(2, 1), 0}}}}, + {"BatteryState", + {{"CHARGED", {SCHEMA_VERSION(2, 1), 0}}, + {"CHARGING", {SCHEMA_VERSION(2, 1), 0}}, + {"DISCHARGED", {SCHEMA_VERSION(2, 1), 0}}, + {"DISCHARGING", {SCHEMA_VERSION(2, 1), 0}}}}, {"FeaturePersisitentId", {}}, {"SensorState", {}}, {"ComponentData", {}}, @@ -124,8 +228,17 @@ Validation ControlledVocabularies { {"MeasurementType", {}}, {"MeasurementValue", {}}, {"MeasurementUnits", {}}, - {"CharacteristicStatus", {{"BASIC_OR_THEORETIC_EXACT_DIMENSION", { SCHEMA_VERSION(2, 2), 0} }, {"FAIL", { SCHEMA_VERSION(2, 2), 0} }, {"INDETERMINATE", { SCHEMA_VERSION(2, 2), 0} }, {"NOT_ANALYZED", { SCHEMA_VERSION(2, 2), 0} }, {"PASS", { SCHEMA_VERSION(2, 2), 0} }, {"REWORK", { SCHEMA_VERSION(2, 2), 0} }, {"SYSTEM_ERROR", { SCHEMA_VERSION(2, 2), 0} }, {"UNDEFINED", { SCHEMA_VERSION(2, 2), 0} }}}, - {"UncertaintyType", {{"COMBINED", { SCHEMA_VERSION(2, 2), 0} }, {"MEAN", { SCHEMA_VERSION(2, 2), 0} }}}, + {"CharacteristicStatus", + {{"BASIC_OR_THEORETIC_EXACT_DIMENSION", {SCHEMA_VERSION(2, 2), 0}}, + {"FAIL", {SCHEMA_VERSION(2, 2), 0}}, + {"INDETERMINATE", {SCHEMA_VERSION(2, 2), 0}}, + {"NOT_ANALYZED", {SCHEMA_VERSION(2, 2), 0}}, + {"PASS", {SCHEMA_VERSION(2, 2), 0}}, + {"REWORK", {SCHEMA_VERSION(2, 2), 0}}, + {"SYSTEM_ERROR", {SCHEMA_VERSION(2, 2), 0}}, + {"UNDEFINED", {SCHEMA_VERSION(2, 2), 0}}}}, + {"UncertaintyType", + {{"COMBINED", {SCHEMA_VERSION(2, 2), 0}}, {"MEAN", {SCHEMA_VERSION(2, 2), 0}}}}, {"Uncertainty", {}}, {"AlarmLimits", {}}, {"ControlLimits", {}}, @@ -135,5 +248,4 @@ Validation ControlledVocabularies { {"ActivePowerSource", {}}, {"LocationNarrative", {}}, {"Thickness", {}}, - {"LocationSpatialGeographic", {}} -}; \ No newline at end of file + {"LocationSpatialGeographic", {}}}; \ No newline at end of file diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index c6df2c858..324f9ddd5 100644 --- a/src/mtconnect/validation/observations.hpp +++ b/src/mtconnect/validation/observations.hpp @@ -31,7 +31,9 @@ namespace mtconnect { namespace observations { /// @brief Validation type for observations - using Validation = std::unordered_map>>; + using Validation = + std::unordered_map>>; /// @brief Global Validations for Event Observation's Controlled Vocabularies /// diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt index 0527fcf0b..c4f0a1a0a 100644 --- a/test_package/CMakeLists.txt +++ b/test_package/CMakeLists.txt @@ -219,6 +219,8 @@ add_agent_test(asset_buffer TRUE asset) add_agent_test(component_parameters TRUE asset) add_agent_test(asset_hash TRUE asset) add_agent_test(physical_asset FALSE asset) +add_agent_test(pallet FALSE asset) +add_agent_test(fixture FALSE asset) add_agent_test(agent_device TRUE device_model) add_agent_test(component FALSE device_model) diff --git a/test_package/data_item_mapping_test.cpp b/test_package/data_item_mapping_test.cpp index 7c69b4637..a17523e1b 100644 --- a/test_package/data_item_mapping_test.cpp +++ b/test_package/data_item_mapping_test.cpp @@ -368,21 +368,21 @@ TEST_F(DataItemMappingTest, should_map_an_event_data_set) TEST_F(DataItemMappingTest, should_map_a_sample_data_set) { auto di = makeDataItem({{"id", "a"s}, - {"type", "SOMETHING"s}, - {"category", "SAMPLE"s}, - {"representation", "DATA_SET"s}}); - + {"type", "SOMETHING"s}, + {"category", "SAMPLE"s}, + {"representation", "DATA_SET"s}}); + auto ts = makeTimestamped({"a", "a=1 b=2 c={3}"}); auto observations = (*m_mapper)(ts); auto oblist = observations->getValue(); ASSERT_EQ(1, oblist.size()); - + auto set = dynamic_pointer_cast(oblist.front()); ASSERT_TRUE(set); ASSERT_EQ("SomethingDataSet", set->getName()); - + ASSERT_EQ(di, set->getDataItem()); - + auto &ds = set->getValue(); ASSERT_EQ(3, ds.size()); ASSERT_EQ(1, get(ds.find("a"_E)->m_value)); @@ -390,7 +390,6 @@ TEST_F(DataItemMappingTest, should_map_a_sample_data_set) ASSERT_EQ("3", get(ds.find("c"_E)->m_value)); } - TEST_F(DataItemMappingTest, should_map_an_event_table) { auto di = makeDataItem( @@ -427,39 +426,40 @@ TEST_F(DataItemMappingTest, should_map_an_event_table) TEST_F(DataItemMappingTest, should_map_an_sample_table) { - auto di = makeDataItem( - {{"id", "a"s}, {"type", "SOMETHING"s}, {"category", "SAMPLE"s}, {"representation", "TABLE"s}}); - + auto di = makeDataItem({{"id", "a"s}, + {"type", "SOMETHING"s}, + {"category", "SAMPLE"s}, + {"representation", "TABLE"s}}); + auto ts = makeTimestamped({"a", "a={c=1 n=3.0} b={d=2 e=3} c={x=abc y=def}"}); auto observations = (*m_mapper)(ts); auto oblist = observations->getValue(); ASSERT_EQ(1, oblist.size()); - + auto set = dynamic_pointer_cast(oblist.front()); ASSERT_TRUE(set); - + ASSERT_EQ(di, set->getDataItem()); ASSERT_EQ("SomethingTable", set->getName()); - + auto &ds = set->getValue(); ASSERT_EQ(3, ds.size()); auto a = get(ds.find("a"_E)->m_value); ASSERT_EQ(2, a.size()); ASSERT_EQ(1, get(a.find("c"_E)->m_value)); ASSERT_EQ(3.0, get(a.find("n"_E)->m_value)); - + auto b = get(ds.find("b"_E)->m_value); ASSERT_EQ(2, a.size()); ASSERT_EQ(2, get(b.find("d"_E)->m_value)); ASSERT_EQ(3, get(b.find("e"_E)->m_value)); - + auto c = get(ds.find("c"_E)->m_value); ASSERT_EQ(2, c.size()); ASSERT_EQ("abc", get(c.find("x"_E)->m_value)); ASSERT_EQ("def", get(c.find("y"_E)->m_value)); } - TEST_F(DataItemMappingTest, should_handle_data_set_reset_trigger) { makeDataItem({{"id", "a"s}, diff --git a/test_package/fixture_test.cpp b/test_package/fixture_test.cpp new file mode 100644 index 000000000..36cc02e8f --- /dev/null +++ b/test_package/fixture_test.cpp @@ -0,0 +1,251 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Ensure that gtest is the first header otherwise Windows raises an error +#include +// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) + +#include +#include +#include +#include +#include +#include +#include + +#include "json_helper.hpp" +#include "mtconnect/agent.hpp" +#include "mtconnect/asset/asset.hpp" +#include "mtconnect/asset/fixture.hpp" +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/entity/json_printer.hpp" +#include "mtconnect/entity/xml_parser.hpp" +#include "mtconnect/entity/xml_printer.hpp" +#include "mtconnect/printer//xml_printer.hpp" +#include "mtconnect/printer//xml_printer_helper.hpp" +#include "mtconnect/source/adapter/adapter.hpp" + +using json = nlohmann::json; +using namespace std; +using namespace mtconnect; +using namespace mtconnect::entity; +using namespace mtconnect::source::adapter; +using namespace mtconnect::asset; +using namespace mtconnect::printer; + +// main +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +class FixtureTest : public testing::Test +{ +protected: + void SetUp() override + { + Fixture::registerAsset(); + m_writer = make_unique(true); + } + + void TearDown() override { m_writer.reset(); } + + std::unique_ptr m_writer; +}; + +TEST_F(FixtureTest, minimal_fixture_definition) +{ + using namespace date; + const auto doc = R"DOC( + + 2022-05-20 + 2022-05-21 + 2022-05-22 + 2022-05-23 + + 5.1 + 1.27 + + XXXYYY + 12345 + CLAMP + MOUNT + +)DOC"; + + ErrorList errors; + entity::XmlParser parser; + + auto entity = parser.parse(Asset::getRoot(), doc, errors); + ASSERT_EQ(0, errors.size()); + + auto asset = dynamic_cast(entity.get()); + ASSERT_NE(nullptr, asset); + + ASSERT_EQ("7ae770f0-c11e-013a-c34c-4e7f553bbb76", asset->getAssetId()); + + ASSERT_FALSE(asset->getTimestamp()); + ASSERT_FALSE(asset->getDeviceUuid()); + + auto date = asset->get("ManufactureDate"); + auto ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(20, unsigned(ymd.day())); + + date = asset->get("CalibrationDate"); + ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(21, unsigned(ymd.day())); + + date = asset->get("InspectionDate"); + ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(22, unsigned(ymd.day())); + + date = asset->get("NextInspectionDate"); + ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(23, unsigned(ymd.day())); + + ASSERT_EQ("XXXYYY", asset->get("FixtureId")); + ASSERT_EQ(12345, asset->get("FixtureNumber")); + ASSERT_EQ("CLAMP", asset->get("ClampingMethod")); + ASSERT_EQ("MOUNT", asset->get("MountingMethod")); + + auto meas = asset->getList("Measurements"); + ASSERT_TRUE(meas); + ASSERT_EQ(2, meas->size()); + + auto it = meas->begin(); + ASSERT_EQ("Length", (*it)->getName()); + ASSERT_EQ("MILLIMETER", get((*it)->getProperty("units"))); + ASSERT_EQ(5.0, get((*it)->getProperty("nominal"))); + ASSERT_EQ(4.95, get((*it)->getProperty("minimum"))); + ASSERT_EQ(5.2, get((*it)->getProperty("maximum"))); + ASSERT_EQ(5.1, get((*it)->getProperty("VALUE"))); + + it++; + ASSERT_EQ("Diameter", (*it)->getName()); + ASSERT_EQ("MILLIMETER", get((*it)->getProperty("units"))); + ASSERT_EQ(1.25, get((*it)->getProperty("nominal"))); + ASSERT_EQ(0.95, get((*it)->getProperty("minimum"))); + ASSERT_EQ(1.4, get((*it)->getProperty("maximum"))); + ASSERT_EQ(1.27, get((*it)->getProperty("VALUE"))); +} + +TEST_F(FixtureTest, should_round_trip_xml) +{ + using namespace date; + const auto doc = + R"DOC( + 2022-05-20T00:00:00Z + 2022-05-21T00:00:00Z + 2022-05-22T00:00:00Z + 2022-05-23T00:00:00Z + + 5.1 + 1.27 + + XXXYYY + 12345 + CLAMP + MOUNT + +)DOC"; + + ErrorList errors; + entity::XmlParser parser; + + auto entity = parser.parse(Asset::getRoot(), doc, errors); + ASSERT_EQ(0, errors.size()); + + entity::XmlPrinter printer; + printer.print(*m_writer, entity, {"x"}); + string content = m_writer->getContent(); + + ASSERT_EQ(doc, content); +} + +TEST_F(FixtureTest, should_generate_json) +{ + using namespace date; + const auto doc = + R"DOC( + 2022-05-20T00:00:00Z + 2022-05-21T00:00:00Z + 2022-05-22T00:00:00Z + 2022-05-23T00:00:00Z + + 5.1 + 1.27 + + XXXYYY + 12345 + CLAMP + MOUNT + +)DOC"; + + ErrorList errors; + entity::XmlParser parser; + + auto entity = parser.parse(Asset::getRoot(), doc, errors); + ASSERT_EQ(0, errors.size()); + + entity::JsonEntityPrinter jsonPrinter(2, true); + auto json = jsonPrinter.print(entity); + + ASSERT_EQ(R"({ + "Fixture": { + "CalibrationDate": "2022-05-21T00:00:00Z", + "ClampingMethod": "CLAMP", + "FixtureId": "XXXYYY", + "FixtureNumber": 12345, + "InspectionDate": "2022-05-22T00:00:00Z", + "ManufactureDate": "2022-05-20T00:00:00Z", + "Measurements": { + "Diameter": [ + { + "value": 1.27, + "maximum": 1.4, + "minimum": 0.95, + "nominal": 1.25, + "units": "MILLIMETER" + } + ], + "Length": [ + { + "value": 5.1, + "maximum": 5.2, + "minimum": 4.95, + "nominal": 5.0, + "units": "MILLIMETER" + } + ] + }, + "MountingMethod": "MOUNT", + "NextInspectionDate": "2022-05-23T00:00:00Z", + "assetId": "7ae770f0-c11e-013a-c34c-4e7f553bbb76" + } +})", + json); +} diff --git a/test_package/json_mapping_test.cpp b/test_package/json_mapping_test.cpp index 58398a123..72a0ee72e 100644 --- a/test_package/json_mapping_test.cpp +++ b/test_package/json_mapping_test.cpp @@ -106,7 +106,7 @@ class JsonMappingTest : public testing::Test cerr << "Errors occurred during make data item" << endl; for (auto &e : errors) { - cerr << " " << e->getEntity() << ": " << e->what() << endl; + cerr << " " << e->getEntity() << ": " << e->what() << endl; } return nullptr; } @@ -1063,7 +1063,7 @@ TEST_F(JsonMappingTest, should_skip_erroneous_array) auto dev = makeDevice("Device", {{"id", "device"s}, {"name", "device"s}, {"uuid", "device"s}}); makeDataItem("device", {{"id", "a"s}, {"type", "EXECUTION"s}, {"category", "EVENT"s}}); makeDataItem("device", {{"id", "b"s}, {"type", "CONTROLLER_MODE"s}, {"category", "EVENT"s}}); - + Properties props {{"VALUE", R"( { "timestamp": "2023-11-09T11:20:00Z", @@ -1079,18 +1079,18 @@ TEST_F(JsonMappingTest, should_skip_erroneous_array) }, "b": "MANUAL" })"s}}; - + auto jmsg = std::make_shared("JsonMessage", props); jmsg->m_device = dev; - + auto res = (*m_mapper)(std::move(jmsg)); ASSERT_TRUE(res); - + auto value = res->getValue(); ASSERT_TRUE(std::holds_alternative(value)); auto list = get(value); ASSERT_EQ(1, list.size()); - + auto obs = dynamic_pointer_cast(list.front()); ASSERT_TRUE(obs); ASSERT_EQ("ControllerMode", obs->getName()); @@ -1104,7 +1104,7 @@ TEST_F(JsonMappingTest, should_skip_erroneous_table) auto dev = makeDevice("Device", {{"id", "device"s}, {"name", "device"s}, {"uuid", "device"s}}); makeDataItem("device", {{"id", "a"s}, {"type", "EXECUTION"s}, {"category", "EVENT"s}}); makeDataItem("device", {{"id", "b"s}, {"type", "CONTROLLER_MODE"s}, {"category", "EVENT"s}}); - + Properties props {{"VALUE", R"( { "timestamp": "2023-11-09T11:20:00Z", @@ -1128,18 +1128,18 @@ TEST_F(JsonMappingTest, should_skip_erroneous_table) }, "b": "MANUAL" })"s}}; - + auto jmsg = std::make_shared("JsonMessage", props); jmsg->m_device = dev; - + auto res = (*m_mapper)(std::move(jmsg)); ASSERT_TRUE(res); - + auto value = res->getValue(); ASSERT_TRUE(std::holds_alternative(value)); auto list = get(value); ASSERT_EQ(1, list.size()); - + auto obs = dynamic_pointer_cast(list.front()); ASSERT_TRUE(obs); ASSERT_EQ("ControllerMode", obs->getName()); diff --git a/test_package/mqtt_sink_test.cpp b/test_package/mqtt_sink_test.cpp index 54d2a27dc..0da157089 100644 --- a/test_package/mqtt_sink_test.cpp +++ b/test_package/mqtt_sink_test.cpp @@ -249,21 +249,21 @@ TEST_F(MqttSinkTest, mqtt_sink_should_publish_Sample) auto handler = make_unique(); bool gotSample = false; bool first = true; - handler->m_receive = [&gotSample, &first](std::shared_ptr client, const std::string &topic, - const std::string &payload) { + handler->m_receive = [&gotSample, &first](std::shared_ptr client, + const std::string &topic, const std::string &payload) { if (first) { first = false; } else { - EXPECT_EQ("MTConnect/Sample/000", topic); + EXPECT_EQ("MTConnect/Sample/000", topic); - auto jdoc = json::parse(payload); - auto streams = jdoc.at("/MTConnectStreams/Streams/0/DeviceStream"_json_pointer); - EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); + auto jdoc = json::parse(payload); + auto streams = jdoc.at("/MTConnectStreams/Streams/0/DeviceStream"_json_pointer); + EXPECT_EQ(string("LinuxCNC"), streams.at("/name"_json_pointer).get()); - gotSample = true; + gotSample = true; } }; diff --git a/test_package/observation_validation_test.cpp b/test_package/observation_validation_test.cpp index 1fe9c7fab..f2e014848 100644 --- a/test_package/observation_validation_test.cpp +++ b/test_package/observation_validation_test.cpp @@ -224,16 +224,15 @@ TEST_F(ObservationValidationTest, should_be_invalid_if_entry_has_not_been_introd { ErrorList errors; m_dataItem = - DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, errors); - + DataItem::make({{"id", "exec"s}, {"category", "EVENT"s}, {"type", "EXECUTION"s}}, errors); + auto contract = static_cast(m_context->m_contract.get()); contract->m_schemaVersion = SCHEMA_VERSION(1, 4); - + auto event = Observation::make(m_dataItem, {{"VALUE", "WAIT"s}}, m_time, errors); - + auto evt = (*m_validator)(std::move(event)); auto quality = evt->get("quality"); ASSERT_EQ("INVALID", quality); ASSERT_FALSE(evt->hasProperty("deprecated")); } - diff --git a/test_package/pallet_test.cpp b/test_package/pallet_test.cpp new file mode 100644 index 000000000..a8eb5f5ce --- /dev/null +++ b/test_package/pallet_test.cpp @@ -0,0 +1,256 @@ +// +// Copyright Copyright 2009-2024, AMT – The Association For Manufacturing Technology (“AMT”) +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Ensure that gtest is the first header otherwise Windows raises an error +#include +// Keep this comment to keep gtest.h above. (clang-format off/on is not working here!) + +#include +#include +#include +#include +#include +#include +#include + +#include "json_helper.hpp" +#include "mtconnect/agent.hpp" +#include "mtconnect/asset/asset.hpp" +#include "mtconnect/asset/pallet.hpp" +#include "mtconnect/entity/entity.hpp" +#include "mtconnect/entity/json_printer.hpp" +#include "mtconnect/entity/xml_parser.hpp" +#include "mtconnect/entity/xml_printer.hpp" +#include "mtconnect/printer//xml_printer.hpp" +#include "mtconnect/printer//xml_printer_helper.hpp" +#include "mtconnect/source/adapter/adapter.hpp" + +using json = nlohmann::json; +using namespace std; +using namespace mtconnect; +using namespace mtconnect::entity; +using namespace mtconnect::source::adapter; +using namespace mtconnect::asset; +using namespace mtconnect::printer; + +// main +int main(int argc, char *argv[]) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +class PalletTest : public testing::Test +{ +protected: + void SetUp() override + { + Pallet::registerAsset(); + m_writer = make_unique(true); + } + + void TearDown() override { m_writer.reset(); } + + std::unique_ptr m_writer; +}; + +TEST_F(PalletTest, minimal_pallet_definition) +{ + using namespace date; + const auto doc = R"DOC( + + 2022-05-20 + 2022-05-21 + 2022-05-22 + 2022-05-23 + + 5.1 + 1.27 + + MACHINE + XXXYYY + 12345 + CLAMP + MOUNT + +)DOC"; + + ErrorList errors; + entity::XmlParser parser; + + auto entity = parser.parse(Asset::getRoot(), doc, errors); + ASSERT_EQ(0, errors.size()); + + auto asset = dynamic_cast(entity.get()); + ASSERT_NE(nullptr, asset); + + ASSERT_EQ("7ae770f0-c11e-013a-c34c-4e7f553bbb76", asset->getAssetId()); + + ASSERT_FALSE(asset->getTimestamp()); + ASSERT_FALSE(asset->getDeviceUuid()); + + auto date = asset->get("ManufactureDate"); + auto ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(20, unsigned(ymd.day())); + + date = asset->get("CalibrationDate"); + ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(21, unsigned(ymd.day())); + + date = asset->get("InspectionDate"); + ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(22, unsigned(ymd.day())); + + date = asset->get("NextInspectionDate"); + ymd = year_month_day(floor(date)); + ASSERT_EQ(2022, int(ymd.year())); + ASSERT_EQ(5, unsigned(ymd.month())); + ASSERT_EQ(23, unsigned(ymd.day())); + + ASSERT_EQ("MACHINE", asset->get("Type")); + ASSERT_EQ("XXXYYY", asset->get("PalletId")); + ASSERT_EQ(12345, asset->get("PalletNumber")); + ASSERT_EQ("CLAMP", asset->get("ClampingMethod")); + ASSERT_EQ("MOUNT", asset->get("MountingMethod")); + + auto meas = asset->getList("Measurements"); + ASSERT_TRUE(meas); + ASSERT_EQ(2, meas->size()); + + auto it = meas->begin(); + ASSERT_EQ("Length", (*it)->getName()); + ASSERT_EQ("MILLIMETER", get((*it)->getProperty("units"))); + ASSERT_EQ(5.0, get((*it)->getProperty("nominal"))); + ASSERT_EQ(4.95, get((*it)->getProperty("minimum"))); + ASSERT_EQ(5.2, get((*it)->getProperty("maximum"))); + ASSERT_EQ(5.1, get((*it)->getProperty("VALUE"))); + + it++; + ASSERT_EQ("Diameter", (*it)->getName()); + ASSERT_EQ("MILLIMETER", get((*it)->getProperty("units"))); + ASSERT_EQ(1.25, get((*it)->getProperty("nominal"))); + ASSERT_EQ(0.95, get((*it)->getProperty("minimum"))); + ASSERT_EQ(1.4, get((*it)->getProperty("maximum"))); + ASSERT_EQ(1.27, get((*it)->getProperty("VALUE"))); +} + +TEST_F(PalletTest, should_round_trip_xml) +{ + using namespace date; + const auto doc = + R"DOC( + 2022-05-20T00:00:00Z + 2022-05-21T00:00:00Z + 2022-05-22T00:00:00Z + 2022-05-23T00:00:00Z + + 5.1 + 1.27 + + MACHINE + XXXYYY + 12345 + CLAMP + MOUNT + +)DOC"; + + ErrorList errors; + entity::XmlParser parser; + + auto entity = parser.parse(Asset::getRoot(), doc, errors); + ASSERT_EQ(0, errors.size()); + + entity::XmlPrinter printer; + printer.print(*m_writer, entity, {"x"}); + string content = m_writer->getContent(); + + ASSERT_EQ(doc, content); +} + +TEST_F(PalletTest, should_generate_json) +{ + using namespace date; + const auto doc = + R"DOC( + 2022-05-20T00:00:00Z + 2022-05-21T00:00:00Z + 2022-05-22T00:00:00Z + 2022-05-23T00:00:00Z + + 5.1 + 1.27 + + MACHINE + XXXYYY + 12345 + CLAMP + MOUNT + +)DOC"; + + ErrorList errors; + entity::XmlParser parser; + + auto entity = parser.parse(Asset::getRoot(), doc, errors); + ASSERT_EQ(0, errors.size()); + + entity::JsonEntityPrinter jsonPrinter(2, true); + auto json = jsonPrinter.print(entity); + + ASSERT_EQ(R"({ + "Pallet": { + "CalibrationDate": "2022-05-21T00:00:00Z", + "ClampingMethod": "CLAMP", + "InspectionDate": "2022-05-22T00:00:00Z", + "ManufactureDate": "2022-05-20T00:00:00Z", + "Measurements": { + "Diameter": [ + { + "value": 1.27, + "maximum": 1.4, + "minimum": 0.95, + "nominal": 1.25, + "units": "MILLIMETER" + } + ], + "Length": [ + { + "value": 5.1, + "maximum": 5.2, + "minimum": 4.95, + "nominal": 5.0, + "units": "MILLIMETER" + } + ] + }, + "MountingMethod": "MOUNT", + "NextInspectionDate": "2022-05-23T00:00:00Z", + "PalletId": "XXXYYY", + "PalletNumber": 12345, + "Type": "MACHINE", + "assetId": "7ae770f0-c11e-013a-c34c-4e7f553bbb76" + } +})", + json); +} diff --git a/test_package/physical_asset_test.cpp b/test_package/physical_asset_test.cpp index dbfdf0dd7..f451f03a3 100644 --- a/test_package/physical_asset_test.cpp +++ b/test_package/physical_asset_test.cpp @@ -64,15 +64,12 @@ class PhysicalAssetTest : public testing::Test m_writer = make_unique(true); } - void TearDown() override - { - m_writer.reset(); - } - + void TearDown() override { m_writer.reset(); } + std::unique_ptr m_writer; }; -TEST_F(PhysicalAssetTest, minimal_raw_material_definition) +TEST_F(PhysicalAssetTest, minimal_physical_asset_definition) { using namespace date; const auto doc = R"DOC( @@ -87,49 +84,49 @@ TEST_F(PhysicalAssetTest, minimal_raw_material_definition) )DOC"; - + ErrorList errors; entity::XmlParser parser; - + auto entity = parser.parse(Asset::getRoot(), doc, errors); ASSERT_EQ(0, errors.size()); - + auto asset = dynamic_cast(entity.get()); ASSERT_NE(nullptr, asset); - + ASSERT_EQ("7ae770f0-c11e-013a-c34c-4e7f553bbb76", asset->getAssetId()); - + ASSERT_FALSE(asset->getTimestamp()); ASSERT_FALSE(asset->getDeviceUuid()); - + auto date = asset->get("ManufactureDate"); auto ymd = year_month_day(floor(date)); ASSERT_EQ(2022, int(ymd.year())); ASSERT_EQ(5, unsigned(ymd.month())); ASSERT_EQ(20, unsigned(ymd.day())); - + date = asset->get("CalibrationDate"); ymd = year_month_day(floor(date)); ASSERT_EQ(2022, int(ymd.year())); ASSERT_EQ(5, unsigned(ymd.month())); ASSERT_EQ(21, unsigned(ymd.day())); - + date = asset->get("InspectionDate"); ymd = year_month_day(floor(date)); ASSERT_EQ(2022, int(ymd.year())); ASSERT_EQ(5, unsigned(ymd.month())); ASSERT_EQ(22, unsigned(ymd.day())); - + date = asset->get("NextInspectionDate"); ymd = year_month_day(floor(date)); ASSERT_EQ(2022, int(ymd.year())); ASSERT_EQ(5, unsigned(ymd.month())); ASSERT_EQ(23, unsigned(ymd.day())); - + auto meas = asset->getList("Measurements"); ASSERT_TRUE(meas); ASSERT_EQ(2, meas->size()); - + auto it = meas->begin(); ASSERT_EQ("Length", (*it)->getName()); ASSERT_EQ("MILLIMETER", get((*it)->getProperty("units"))); @@ -137,7 +134,7 @@ TEST_F(PhysicalAssetTest, minimal_raw_material_definition) ASSERT_EQ(4.95, get((*it)->getProperty("minimum"))); ASSERT_EQ(5.2, get((*it)->getProperty("maximum"))); ASSERT_EQ(5.1, get((*it)->getProperty("VALUE"))); - + it++; ASSERT_EQ("Diameter", (*it)->getName()); ASSERT_EQ("MILLIMETER", get((*it)->getProperty("units"))); @@ -151,7 +148,7 @@ TEST_F(PhysicalAssetTest, should_round_trip_xml) { using namespace date; const auto doc = - R"DOC( + R"DOC( 2022-05-20T00:00:00Z 2022-05-21T00:00:00Z 2022-05-22T00:00:00Z @@ -180,7 +177,7 @@ TEST_F(PhysicalAssetTest, should_generate_json) { using namespace date; const auto doc = - R"DOC( + R"DOC( 2022-05-20T00:00:00Z 2022-05-21T00:00:00Z 2022-05-22T00:00:00Z From 6e1375ccb648e33d91da3762afe0c4fcb4efcace Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Wed, 15 Jan 2025 17:25:50 -0500 Subject: [PATCH 127/128] Refactored cutting tool touse common measurement --- src/mtconnect/asset/cutting_tool.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/mtconnect/asset/cutting_tool.cpp b/src/mtconnect/asset/cutting_tool.cpp index 43d5303af..245f0b2a6 100644 --- a/src/mtconnect/asset/cutting_tool.cpp +++ b/src/mtconnect/asset/cutting_tool.cpp @@ -53,18 +53,7 @@ namespace mtconnect { Requirement("nominal", ValueType::DOUBLE, false), Requirement("VALUE", ValueType::DOUBLE, false)})); - static auto measurement = make_shared(Requirements( - {Requirement("significantDigits", ValueType::INTEGER, false), - Requirement("units", false), Requirement("nativeUnits", false), - Requirement("code", false), Requirement("maximum", ValueType::DOUBLE, false), - Requirement("minimum", ValueType::DOUBLE, false), - Requirement("nominal", ValueType::DOUBLE, false), - Requirement("VALUE", ValueType::DOUBLE, false)})); - - static auto measurements = make_shared(Requirements({Requirement( - "Measurement", ValueType::ENTITY, measurement, 1, Requirement::Infinite)})); - measurements->registerMatchers(); - measurements->registerFactory(regex(".+"), measurement); + static auto measurements = PhysicalAsset::getMeasurementsFactory()->deepCopy(); static auto ext = make_shared(); ext->registerFactory(regex(".+"), ext); @@ -83,7 +72,6 @@ namespace mtconnect { item->registerFactory(regex(".+"), ext); item->setAny(true); - measurements->registerMatchers(); item->setOrder({"Description", "CutterStatus", "Locus", "ItemLife", "ProgramToolGroup", "Measurements"}); From a4a52a31743770b31c0c74654133f644c8abce42 Mon Sep 17 00:00:00 2001 From: Will Sobel Date: Tue, 25 Feb 2025 17:17:06 -0500 Subject: [PATCH 128/128] Changes for 2.5 release --- CMakeLists.txt | 4 +- README.md | 2 +- schemas/MTConnectAssets_2.5.xsd | 17484 ++++++++++ schemas/MTConnectAssets_2.5_1.0.xsd | 17463 ++++++++++ schemas/MTConnectDevices_2.5.xsd | 10437 ++++++ schemas/MTConnectDevices_2.5_1.0.xsd | 10430 ++++++ schemas/MTConnectError_2.5.xsd | 4667 +++ schemas/MTConnectError_2.5_1.0.xsd | 4667 +++ schemas/MTConnectStreams_2.5.xsd | 46228 +++++++++++++++++++++++++ schemas/MTConnectStreams_2.5_1.0.xsd | 46228 +++++++++++++++++++++++++ schemas/readme.md | 4 +- 11 files changed, 157610 insertions(+), 4 deletions(-) create mode 100644 schemas/MTConnectAssets_2.5.xsd create mode 100644 schemas/MTConnectAssets_2.5_1.0.xsd create mode 100644 schemas/MTConnectDevices_2.5.xsd create mode 100644 schemas/MTConnectDevices_2.5_1.0.xsd create mode 100644 schemas/MTConnectError_2.5.xsd create mode 100644 schemas/MTConnectError_2.5_1.0.xsd create mode 100644 schemas/MTConnectStreams_2.5.xsd create mode 100644 schemas/MTConnectStreams_2.5_1.0.xsd diff --git a/CMakeLists.txt b/CMakeLists.txt index 589c2ab4c..758a427e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,8 +2,8 @@ set(AGENT_VERSION_MAJOR 2) set(AGENT_VERSION_MINOR 5) set(AGENT_VERSION_PATCH 0) -set(AGENT_VERSION_BUILD 0) -set(AGENT_VERSION_RC "RC4") +set(AGENT_VERSION_BUILD 1) +set(AGENT_VERSION_RC "") # This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent cmake_minimum_required(VERSION 3.23 FATAL_ERROR) diff --git a/README.md b/README.md index 089b72be4..c911b749c 100755 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ the devices and the location of the adapter. Pre-built binary releases for Windows are available from [Releases](https://github.com/mtconnect/cppagent/releases) for those who do not want to build the agent themselves. For *NIX users, you will need libxml2, cppunit, and cmake as well as build essentials. -Version 2.5.0 Added validation of observations in the stream +Version 2.5.0 Support for version 2.5. Added validation of observations in the stream and WebSockets support. Version 2.4.0 Added support for version 2.4 diff --git a/schemas/MTConnectAssets_2.5.xsd b/schemas/MTConnectAssets_2.5.xsd new file mode 100644 index 000000000..7f946cf45 --- /dev/null +++ b/schemas/MTConnectAssets_2.5.xsd @@ -0,0 +1,17484 @@ + + + + + + + + root entity of an {{term(MTConnectAssets Response Document)}} that + contains the {{term(Asset Information Model)}} of {{block(Asset)}} + types. ![MTConnectAssets](figures/MTConnectAssets.png + "MTConnectAssets"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectAssets)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + The sender of the message + + + + + + + + The date and time the document was created + + + + + + + + A sequence number + + + + + + + + + + + A debugging flag for testing. + + + + + + + + The instance number of the agent, used for fault tolerance + + + + + + + + + + + The size of the agents buffer + + + + + + + + + + + The time the sample was reported + + + + + + + + The time a sample occurred + + + + + + + + A version number + + + + + + + + A short name for any element + + + + + + + + A universally unique id that uniquely identifies the element for + it's entire life + + + + + + + + A serial number for a piece of equipment + + + + + + + + The measurement source + + + + + + + + A sample rate in milliseconds per sample + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + + An identifier + + + + + + + + The number significant digits + + + + + + + + The item's reference to the Device model composition + + + + + + + + A length of time in seconds + + + + + + + + A flag indicating the item has been removed + + + + + + + + The key for adata set + + + + + + + + A timestamp in 8601 format of the last update of the Device information + for any device + + + + + + + + The unique id of the asset + + + + + + + + An asset type + + + + + + + + The maximum number of assets + + + + + + + + + + + The number of assets + + + + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + The limit of a value + + + + + + + + Common floating point sample value + + + + + + + + + + + + A three dimensional value 'X Y Z' or 'A B C' + + + + + + + + + + + A description + + + + + + + + Extended tyoe for The types of measurements available + + + + + + + + + + The types of measurements available + + + + + + + positive rate of change of velocity. + + + + + + + accumulated time for an activity or event. + + + + + + + strength of electrical current. **DEPRECATED** in *Version 1.6*. + Replaced by `AMPERAGE_AC` and `AMPERAGE_DC`. + + + + + + + angular position. + + + + + + + positive rate of change of angular velocity. + + + + + + + rate of change of angular position. + + + + + + + feedrate of a linear axis. + + + + + + + fluid capacity of an object or container. + + + + + + + geometric capacity of an object or container. + + + + + + + percentage of one component within a mixture of components. + + + + + + + ability of a material to conduct electricity. + + + + + + + speed difference (relative velocity) between the cutting mechanism + and the surface of the workpiece it is operating on. + + + + + + + volumetric mass of a material per unit volume of that material. + + + + + + + rate of change in spatial volume of material deposited in an + additive manufacturing process. + + + + + + + density of the material deposited in an additive manufacturing + process per unit of volume. + + + + + + + mass of the material deposited in an additive manufacturing process. + + + + + + + rate at which a spatial volume of material is deposited in an + additive manufacturing process. + + + + + + + spatial volume of material to be deposited in an additive + manufacturing process. + + + + + + + change in position of an object. + + + + + + + {{block(Wattage)}} used or generated by a component over an interval + of time. + + + + + + + amount of time a piece of equipment or a sub-part of a piece of + equipment has performed specific activities. + + + + + + + amount of a substance remaining compared to the planned maximum + amount of that substance. + + + + + + + rate of flow of a fluid. + + + + + + + number of occurrences of a repeating event per unit time. + + + + + + + position in three-dimensional space. **DEPRECATED** in Version 1.1. + + + + + + + length of an object. + + + + + + + level of a resource. **DEPRECATED** in *Version 1.2*. See + `FILL_LEVEL`. + + + + + + + {{term(force)}} applied to a mass in one direction only. + + + + + + + actual versus the standard rating of a piece of equipment. + + + + + + + mass of an object(s) or an amount of material. + + + + + + + feedrate for the axes, or a single axis, associated with a + {{block(Path)}} component. + + + + + + + feedrate for the axes, or a single axis. + + + + + + + position of a control point associated with a {{block(Controller)}} + or a {{block(Path)}}. + + + + + + + acidity or alkalinity of a solution. + + + + + + + point along an axis in a {{term(cartesian coordinate system)}}. + + + + + + + ratio of real power flowing to a load to the apparent power in that + AC circuit. + + + + + + + force per unit area measured relative to atmospheric pressure. + Commonly referred to as gauge pressure. + + + + + + + amount of time a piece of equipment has performed different types of + activities associated with the process being performed at that piece + of equipment. + + + + + + + degree to which a substance opposes the passage of an electric + current. + + + + + + + rotational speed of a rotary axis. + + + + + + + sound level or sound pressure level relative to atmospheric + pressure. + + + + + + + rotational speed of the rotary axis. **DEPRECATED** in *Version + 1.2*. Replaced by `ROTARY_VELOCITY`. + + + + + + + amount of deformation per unit length of an object when a load is + applied. + + + + + + + degree of hotness or coldness measured on a definite scale. + + + + + + + force that stretches or elongates an object. + + + + + + + angular displacement. + + + + + + + turning force exerted on an object or by an object. + + + + + + + rate of change of position of a {{block(Component)}}. + + + + + + + fluid's resistance to flow. + + + + + + + electrical potential between two points. **DEPRECATED** in *Version + 1.6*. Replaced by `VOLTAGE_AC` and `VOLTAGE_DC`. + + + + + + + apparent power in an electrical circuit, equal to the product of + root-mean-square (RMS) voltage and RMS current (commonly referred to + as VA). + + + + + + + reactive power in an AC electrical circuit (commonly referred to as + VAR). + + + + + + + fluid volume of an object or container. + + + + + + + geometric volume of an object or container. + + + + + + + power flowing through or dissipated by an electrical circuit or + piece of equipment. + + + + + + + electrical current that reverses direction at regular short + intervals. + + + + + + + electric current flowing in one direction only. + + + + + + + electrical potential between two points in an electrical circuit in + which the current periodically reverses direction. + + + + + + + electrical potential between two points in an electrical circuit in + which the current is unidirectional. + + + + + + + dimension of an entity relative to the X direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Y direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Z direction of the referenced + coordinate system. + + + + + + + dimension of a diameter. + + + + + + + angular position of a plane or vector relative to a {{term(cartesian + coordinate system)}} + + + + + + + amount of water vapor present expressed as a percent to reach + saturation at the same temperature. + + + + + + + amount of water vapor expressed in grams per cubic meter. + + + + + + + ratio of the water vapor present over the total weight of the water + vapor and air present expressed as a percent. + + + + + + + average rate of change of values for data items in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + average rate of change of values for assets in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + change of pressure per unit time. + + + + + + + negative rate of change of velocity. + + + + + + + negative rate of change of angular velocity. + + + + + + + force per unit area measured relative to a vacuum. + + + + + + + percentage open where 100% is fully open and 0% is fully closed. + + + + + + + temperature at which moisture begins to condense, corresponding to + saturation for a given absolute humidity. + + + + + + + force relative to earth's gravity. + + + + + + + acceleration relative to Earth's gravity of 9.80665 + `METER/SECOND^2`. + + + + + + + maximum rated charge a battery is capable of maintaining based on + the battery discharging at a specified current over a specified time + period. + + + + + + + value of current being drawn from the {{block(Component)}}. + + + + + + + value of the current being supplied to the {{block(Component)}} for + the purpose of charging. + + + + + + + value of the battery's present capacity expressed as a + percentage of the battery's maximum rated capacity. + + + + + + + difference between actual and commanded position at the end of a + motion. + + + + + + + difference between actual and commanded position at any specific + point in time during a motion. + + + + + + + difference between the commanded encoder/resolver position, and the + actual encoder/resolver position when motion is complete. + + + + + + + angular difference between the commanded encoder/resolver position, + and the actual encoder/resolver position when motion is complete. + + + + + + + difference between the commanded encoder/resolver position and the + actual encoder/resolver position at any specified point in time + during a motion. + + + + + + + angular difference between the commanded encoder/resolver position + and the actual encoder/resolver position at any specified point in + time during a motion. + + + + + + + absolute value of the change in position along a vector. + + + + + + + absolute value of the change in angular position around a vector + + + + + + + point in a {{term(cartesian coordinate system)}}. + + + + + + + set of axes currently associated with a {{block(Path)}} or + {{block(Controller)}}. + + + + + + + operational state of an apparatus for moving or controlling a + mechanism or system. + + + + + + + **DEPRECATED:** Replaced with `CONDITION` category data items in + Version 1.1.0. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been added or + changed. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been removed. + + + + + + + {{term(agent)}}'s ability to communicate with the data source. + + + + + + + describes the way the axes will be associated to each other. This is + used in conjunction with `COUPLED_AXES` to indicate the way they are + interacting. + + + + + + + value of a signal or calculation issued to adjust the feedrate of an + individual linear type axis. + + + + + + + state of the axis lockout function when power has been removed and + the axis is allowed to move freely. + + + + + + + state of a {{block(Linear)}} or {{block(Rotary)}} component + representing an axis. + + + + + + + line of code or command being executed by a {{block(Controller)}} + entity. + + + + + + + total count of the number of blocks of program code that have been + executed since execution started. + + + + + + + state of an interlock function or control logic state intended to + prevent the associated {{block(Chuck)}} component from being + operated. + + + + + + + operating state of a mechanism that holds a part or stock material + during a manufacturing process. It may also represent a mechanism + that holds any other mechanism in place within a piece of equipment. + + + + + + + programmatic code being executed. **DEPRECATED** in *Version 1.1*. + + + + + + + operating state of a mechanism represented by a + {{block(Composition)}} entity. + + + + + + + current mode of the {{block(Controller)}} component. + + + + + + + setting or operator selection that changes the behavior of a piece + of equipment. + + + + + + + set of associated axes. + + + + + + + time and date code associated with a material or other physical + item. + + + + + + + identifier of another piece of equipment that is temporarily + associated with a component of this piece of equipment to perform a + particular function. + + + + + + + direction of motion. + + + + + + + operational state of a {{block(Door)}} component or composition + element. + + + + + + + state of the emergency stop signal for a piece of equipment, + controller path, or any other component or subsystem of a piece of + equipment. + + + + + + + indication of whether the end of a piece of bar stock being feed by + a bar feeder has been reached. + + + + + + + indication that a piece of equipment, or a sub-part of a piece of + equipment, is performing specific types of activities. + + + + + + + operating state of a {{block(Component)}}. + + + + + + + current intended production status of the {{block(Component)}}. + + + + + + + hardness of a material. + + + + + + + current line of code being executed. **DEPRECATED** in *Version + 1.4.0*. + + + + + + + identifier for a {{block(Block)}} of code in a {{block(Program)}}. + + + + + + + position of a block of program code within a control program. + + + + + + + identifier of a material used or consumed in the manufacturing + process. + + + + + + + identifies the layers of material applied to a part or product as + part of an additive manufacturing process. + + + + + + + information to be transferred from a piece of equipment to a client + software application. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + identifier for a pallet. + + + + + + + aggregate count of parts. + + + + + + + indication designating whether a part or work piece has been + detected or is present. + + + + + + + identifier of a part in a manufacturing operation. + + + + + + + identifier of a part or product moving through the manufacturing + process. **DEPRECATED** in *Version 1.7*. `PART_NUMBER` is now a + `subType` of `PART_KIND_ID`. + + + + + + + value of a signal or calculation issued to adjust the feedrate for + the axes associated with a {{block(Path)}} component that may + represent a single axis or the coordinated movement of multiple + axes. + + + + + + + describes the operational relationship between a {{block(Path)}} + entity and another {{block(Path)}} entity for pieces of equipment + comprised of multiple logical groupings of controlled axes or other + logical operations. + + + + + + + indication of the status of the source of energy for an entity to + allow it to perform its intended function or the state of an + enabling signal providing permission for the entity to perform its + functions. + + + + + + + status of the {{block(Component)}}. **DEPRECATED** in *Version + 1.1.0*. + + + + + + + time and date associated with an activity or event. + + + + + + + name of the logic or motion program being executed by the + {{block(Controller)}} component. + + + + + + + comment or non-executable statement in the control program. + + + + + + + indication of the status of the {{block(Controller)}} components + program editing mode. A program may be edited while another is + executed. + + + + + + + name of the program being edited. This is used in conjunction with + {{block(ProgramEdit)}} when in `ACTIVE` state. + + + + + + + non-executable header section of the control program. + + + + + + + {{term(URI)}} for the source file associated with + {{block(Program)}}. + + + + + + + defines whether the logic or motion program defined by + {{block(Program)}} is being executed from the local memory of the + controller or from an outside source. + + + + + + + indication of the nesting level within a control program that is + associated with the code or instructions that is currently being + executed. + + + + + + + current operating mode for a {{block(Rotary)}} type axis. + + + + + + + percentage change to the velocity of the programmed velocity for a + {{block(Rotary)}} axis. + + + + + + + serial number associated with a {{block(Component)}}, + {{block(Asset)}}, or {{block(Device)}}. + + + + + + + indication of the status of the spindle for a piece of equipment + when power has been removed and it is free to rotate. + + + + + + + identifier of an individual tool asset. + + + + + + + identifier for the tool group associated with a specific tool. + Commonly used to designate spare tools. + + + + + + + identifier of the tool currently in use for a given `Path`. + **DEPRECATED** in *Version 1.2.0*. See `TOOL_ASSET_ID`. + + + + + + + identifier assigned by the {{block(Controller)}} component to a + cutting tool when in use by a piece of equipment. + + + + + + + reference to the tool offset variables applied to the active cutting + tool. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + data whose meaning may change over time due to changes in the + operation of a piece of equipment or the process being executed on + that piece of equipment. + + + + + + + indication of the reason that {{block(Execution)}} is reporting a + value of `WAIT`. + + + + + + + identifier for the type of wire used as the cutting mechanism in + Electrical Discharge Machining or similar processes. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. **DEPRECATION WARNING**: Recommend using + `FIXTURE_ID` instead. + + + + + + + reference to offset variables for a work piece or part. + + + + + + + Operating System (OS) of a {{block(Component)}}. + + + + + + + embedded software of a {{block(Component)}} . + + + + + + + application on a {{block(Component)}}. + + + + + + + software library on a {{block(Component)}} + + + + + + + hardware of a {{block(Component)}}. + + + + + + + network details of a {{block(Component)}}. + + + + + + + three space angular displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + three space linear displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + {{term(UUID)}} of new device added to an {{term(MTConnect Agent)}}. + + + + + + + {{term(UUID)}} of a device removed from an {{term(MTConnect + Agent)}}. + + + + + + + {{term(UUID)}} of the device whose {{term(metadata)}} has changed. + + + + + + + status of the connection between an {{term(adapter)}} and an + {{term(agent)}}. + + + + + + + originator’s software version of the {{term(adapter)}}. + + + + + + + {{term(URI)}} of the {{term(adapter)}}. + + + + + + + reference version of the MTConnect Standard supported by the + {{term(adapter)}}. + + + + + + + {{term(attachment)}} between a sensor and an entity. + + + + + + + state or condition of a part. + + + + + + + identifier of a process being executed by the device. + + + + + + + identifier given to link the individual occurrence to a group of + related occurrences, such as a process step in a process plan. + + + + + + + identifier given to link the individual occurrence to a class of + processes or process definition. + + + + + + + identifier given to a collection of individual parts. + + + + + + + identifier given to link the individual occurrence to a class of + parts, typically distinguished by a particular part design. + + + + + + + identifier given to a distinguishable, individual part. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. **DEPRECATION WARNING**. Recommend using + `CONTROL_LIMITS`. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. **DEPRECATION WARNING**. Recommend using + `SPECIFICATION_LIMITS`. + + + + + + + set of limits used to trigger warning or alarm indicators. + **DEPRECATION WARNING**. Recommend using `ALARM_LIMITS`. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, load materials, parts, or other items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, unload materials, parts, or other + items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, transfer materials, parts, or other + items from one location to another. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, activate or be performed. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, deactivate or cease. + + + + + + + accumulation of the number of times a cyclic function has attempted + to, or is planned to attempt to execute. + + + + + + + state of a valve is one of open, closed, or transitioning between + the states. + + + + + + + state or operating mode of a {{block(Lock)}}. + + + + + + + particular condition of the process occurrence at a specific time. + + + + + + + particular condition of the part occurrence at a specific time. + + + + + + + state of {{block(Component)}} or {{block(Composition)}} that + describes the automatic or manual operation of the entity. + + + + + + + {{term(data set)}} of the number of {{termplural(Asset)}} of a given + type for a {{term(Device)}}. + + + + + + + actions or activities to be performed in support of a piece of + equipment. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. + + + + + + + interpretation of `PART_COUNT`. + + + + + + + time provided by a timing device at a specific point in time. + + + + + + + name of the host computer supplying data. + + + + + + + number of the TCP/IP or UDP/IP port for the connection endpoint. + + + + + + + indication designating whether a leak has been detected. + + + + + + + present status of the battery. + + + + + + + {{term(UUID)}} of a {{term(feature)}}. {{cite(ISO 10303 AP + 242/239)}}. + + + + + + + detection result of a sensor. + + + + + + + {{block(Event)}} that represents a {{block(Component)}} where the + {{block(EntryDefinition)}} identifies the {{block(Component)}} and + the {{block(CellDefinition)}}s define the + {{block(Component)}}'s observed {{block(DataItem)}}s. + + + + + + + properties of each addressable work offset. + + + + + + + properties of each addressable tool offset. + + + + + + + assessing elements of a {{term(feature)}}. + + + + + + + {{term(UUID)}} of the {{term(characteristic)}}. + + + + + + + class of measurement being performed. {{cite(QIF 3:2018 Section + 6.3)}} + + + + + + + measurement based on the measurement type. + + + + + + + engineering units of the measurement. + + + + + + + pass/fail result of the measurement. + + + + + + + method used to compute {{term(standard uncertainty)}}. + + + + + + + {{term(uncertainty)}} specified by {{block(UncertaintyType)}}. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. + + + + + + + set of limits used to trigger warning or alarm indicators. + + + + + + + references the {{block(CuttingToolLifeCycle)}} + {{block(CuttingItem)}} index related to the + {{property(CuttingItem::indices)}} of the currently active cutting + tool edge. + + + + + + + structured information that allows the unambiguous determination of + an object for purposes of identification and location. {{cite(ISO + 19160-4:2017)}} + + + + + + + active energy source for the {{block(Component)}}. + + + + + + + textual description of the location of an object or activity. + + + + + + + dimension between two surfaces of an object, usually the dimension + of smallest measure, for example an additive layer, or a depth of + cut. + + + + + + + absolute geographic location defined by two coordinates, longitude + and latitude and an elevation. + + + + + + + indication that the piece of equipment has experienced a + communications failure. + + + + + + + indication that the value of the data associated with a measured + value or a calculation is outside of an expected range. + + + + + + + indication that an error occurred in the logic program or + programmable logic controller (PLC) associated with a piece of + equipment. + + + + + + + indication that an error occurred in the motion program associated + with a piece of equipment. + + + + + + + general purpose indication associated with an electronic component + of a piece of equipment or a controller that represents a fault that + is not associated with the operator, program, or hardware. + + + + + + + indication of a fault associated with an actuator. + + + + + + + operational state of an {{block(Interface)}}. + + + + + + + operating state of the service to advance material or feed product + to a piece of equipment from a continuous or bulk source. + + + + + + + operating state of the service to change the type of material or + product being loaded or fed to a piece of equipment. + + + + + + + operating state of the service to remove or retract material or + product. + + + + + + + operating state of the service to change the part or product + associated with a piece of equipment to a different part or product. + + + + + + + operating state of the service to load a piece of material or + product. + + + + + + + operating state of the service to unload a piece of material or + product. + + + + + + + operating state of the service to open a chuck. + + + + + + + operating state of the service to open a door. + + + + + + + operating state of the service to close a chuck. + + + + + + + operating state of the service to close a door. + + + + + + + A user variable + + + + + + + + + The types of measurements available + + + + + + + + Extended tyoe for The sub-types for a measurement + + + + + + + + + + The sub-types for a measurement + + + + + + + relating to or derived in the simplest manner from the fundamental + units or measurements. + + + + + + + indication of the operating state of a mechanism. + + + + + + + measured or reported value of an {{term(observation)}}. + + + + + + + all actions, items, or activities being counted independent of the + outcome. + + + + + + + measurement of alternating voltage or current. If not specified + further in statistic, defaults to RMS voltage. **DEPRECATED** in + *Version 1.6*. + + + + + + + A-Scale weighting factor on the frequency scale. + + + + + + + when multiple locations on a piece of bar stock being feed by a bar + feeder are referenced as the indication of whether the end of that + piece of bar stock has been reached. + + + + + + + actions, items, or activities being counted that do not conform to + specification or expectation. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + B-Scale weighting factor on the frequency scale. + + + + + + + directive value including adjustments such as an offset or + overrides. + + + + + + + amount of material consumed from an object or container during a + manufacturing process. + + + + + + + state of the enabling signal or control logic that enables or + disables the function or operation of the entity. + + + + + + + C-Scale weighting factor on the frequency scale. + + + + + + + elapsed time of a temporary halt of action. + + + + + + + DC current or voltage. **DEPRECATED** in *Version 1.6*. + + + + + + + setting or operator selection used to execute a test mode to confirm + the execution of machine functions. + + + + + + + D-Scale weighting factor on the frequency scale. + + + + + + + relating to the expiration or end of useful life for a material or + other physical item. + + + + + + + relating to the first use of a material or other physical item. + + + + + + + actions, items, or activities being counted that conform to + specification or expectation. + + + + + + + relating to or derived from the last {{term(observation)}}. + + + + + + + relating to momentary activation of a function or a movement. + **DEPRECATION WARNING**: May be deprecated in the future. + + + + + + + indication of the position of a mechanism that may move in a lateral + direction. + + + + + + + scale to measure the elasticity of a surface. + + + + + + + reference to a length type tool offset variable. + + + + + + + state of the power source. + + + + + + + direction of motion of a linear motion. + + + + + + + indication that the subparts of a piece of equipment are under load. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + relating to the primary logic or motion program currently being + executed. + + + + + + + relating to maintenance on the piece of equipment. + + + + + + + indication of the state of an operator controlled interlock that can + inhibit the ability to initiate an unclamp action of an + electronically controlled chuck. + + + + + + + related to the production of a material or other physical item. + + + + + + + maximum value. + + + + + + + minimum value. + + + + + + + scale to measure the resistance to scratching of a surface. + + + + + + + indication of the open or closed state of a mechanism. + + + + + + + no weighting factor on the frequency scale. + + + + + + + piece of equipment that is powered or performing any activity. + + + + + + + relating to the person currently responsible for operating the piece + of equipment. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + overridden value. + + + + + + + piece of equipment is powered and functioning or + {{block(Component)}} that are required to remain on are powered. + + + + + + + main or principle. + + + + + + + position provided by a measurement probe. **DEPRECATION WARNING**: + May be deprecated in the future. + + + + + + + relating to production of a part or product on a piece of equipment. + + + + + + + directive value without offsets and adjustments. + + + + + + + reference to a radial type tool offset variable. + + + + + + + performing an operation faster or in less time than nominal rate. + + + + + + + remaining measure or count of an action, object or activity. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + direction of a rotary motion using the right hand rule convention. + + + + + + + identity of a control program that is used to specify the order of + execution of other programs. + + + + + + + relating to the preparation of a piece of equipment for production + or restoring the piece of equipment to a neutral state after + production. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + standard measure of an object or an action. + + + + + + + boundary when an activity or an event commences. + + + + + + + indication of the activation state of a mechanism represented by a + {{block(Composition)}}. + + + + + + + goal of the operation or process. + + + + + + + relating to the end or completion of an activity or event. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + remaining usable measure of an object or action. + + + + + + + indication of the position of a mechanism that may move in a + vertical direction. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + piece of equipment performing any activity, the equipment is active + and performing a function under load or not. + + + + + + + IPV4 network address of the {{block(Component)}}. + + + + + + + IPV6 network address of the {{block(Component)}}. + + + + + + + Gateway for the {{block(Component)}} network. + + + + + + + SubNet mask for the {{block(Component)}} network. + + + + + + + layer2 Virtual Local Network (VLAN) ID for the {{block(Component)}} + network. + + + + + + + Media Access Control Address. The unique physical address of the + network hardware. + + + + + + + identifies whether the connection type is wireless. + + + + + + + license code to validate or activate the hardware or software. + + + + + + + version of the hardware or software. + + + + + + + date the hardware or software was released for general use. + + + + + + + date the hardware or software was installed. + + + + + + + corporate identity for the maker of the hardware or software. + + + + + + + universally unique identifier as specified in ISO 11578 or RFC 4122. + + + + + + + serial number that uniquely identifies a specific part. + + + + + + + material that is used to produce parts. + + + + + + + group of parts tracked as a lot. + + + + + + + group of parts produced in a batch. + + + + + + + material heat number. + + + + + + + particular part design or model. + + + + + + + group of parts having similarities in geometry, manufacturing + process, and/or functions. + + + + + + + word or set of words by which a part is known, addressed, or + referred to. + + + + + + + step in the process plan that this occurrence corresponds to. + + + + + + + process plan that a process occurrence belongs to. + + + + + + + authorization of a process occurrence. + + + + + + + word or set of words by which a process being executed (process + occurrence) by the device is known, addressed, or referred to. + + + + + + + reference to a ISO 10303 Executable. + + + + + + + associated with the completion of an activity or event. + + + + + + + relating to logic or motion program currently executing. + + + + + + + actions or activities that were attempted , but failed to complete + or resulted in an unexpected or unacceptable outcome. + + + + + + + actions or activities that were attempted, but terminated before + they could be completed. + + + + + + + boundary when an activity or an event terminates. + + + + + + + amount discarded. + + + + + + + amount included in the {{term(part)}}. + + + + + + + {{term(request)}} by an {{block(Interface)}} for a task. + + + + + + + {{term(response)}} by an {{block(Interface)}} to a {{term(request)}} + for a task. + + + + + + + phase or segment of a recipe or program. + + + + + + + phase of a recipe process. + + + + + + + process as part of product production; can be a subprocess of a + larger process. + + + + + + + step of a discrete manufacturing process. + + + + + + + observed as a binary data type. + + + + + + + observed as a boolean data type. + + + + + + + observed as a set containing a restricted number of discrete values + where each discrete value is named and unique. {{cite(ISO + 21961:2003, 013)}} + + + + + + + indicated by the presence or existence of something. + + + + + + + model info of the hardware or software. + + + + + + + + + The sub-types for a measurement + + + + + + + + Extended tyoe for Statistical operations on data + + + + + + + + + + Statistical operations on data + + + + + + + mathematical average value calculated for the data item during the + calculation period. + + + + + + + **DEPRECATED** in *Version 1.6*. ~~A measure of the + "peakedness" of a probability distribution; i.e., the + shape of the distribution curve.~~ + + + + + + + maximum or peak value recorded for the data item during the + calculation period. + + + + + + + middle number of a series of numbers. + + + + + + + minimum value recorded for the data item during the calculation + period. + + + + + + + number in a series of numbers that occurs most often. + + + + + + + difference between the maximum and minimum value of a data item + during the calculation period. Also represents Peak-to-Peak + measurement in a waveform. + + + + + + + mathematical Root Mean Square (RMS) value calculated for the data + item during the calculation period. + + + + + + + statistical Standard Deviation value calculated for the data item + during the calculation period. + + + + + + + + + Statistical operations on data + + + + + + + + Extended tyoe for same as {{property(DataItem::units)}}. See + {{package(Device Information Model)}}. + + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + + Extended tyoe for The units supported for the source equipment that can + be converted into MTC Units. + + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + measure of viscosity. + + + + + + + rotational velocity in degrees per minute. + + + + + + + temperature in Fahrenheit. + + + + + + + feet. + + + + + + + feet per minute. + + + + + + + feet per second. + + + + + + + acceleration in feet per second squared. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in feet. + + + + + + + gallons per minute. + + + + + + + measurement of time in hours. + + + + + + + inches. + + + + + + + inches per minute. + + + + + + + inches per second. + + + + + + + acceleration in inches per second squared. + + + + + + + measure of torque in inch pounds. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in inches. + + + + + + + measurement of temperature. + + + + + + + measurement in kilowatt. + + + + + + + kilowatt hours which is 3.6 mega joules. + + + + + + + measurement of rate of flow of a fluid. + + + + + + + velocity in millimeters per minute. + + + + + + + measurement of time in minutes. + + + + + + + unsupported unit. + + + + + + + US pounds. + + + + + + + pressure in pounds per square inch (PSI). + + + + + + + angle in radians. + + + + + + + velocity in radians per minute. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + pressure in Bar. + + + + + + + pressure in Torr. + + + + + + + pressure in Millimeter of Mercury (mmHg). + + + + + + + pascal per minute. + + + + + + + $$MASS\times GRAVITATIONAL_ACCELERATION$$ (g) given in + `METER/SECOND^2`. + + + + + + + acceleration relative to earth's gravity given in + `METER/SECOND^2`. > Note 1 to entry: At different points on + Earth's surface, the free-fall acceleration ranges from 9.764 + to 9.834 m/s2 (Wikipedia: Gravitational Acceleration). The constant + can be customized depending on the location in the universe. > + Note 2 to entry: In the standard, it is assumed that Earth's + average value of gravitational acceleration is 9.90665 m/s2. + + + + + + + electric charge in ampere hour. + + + + + + + change of geometric volume in cubic foot per hour. + + + + + + + change of geometric volume in cubic foot per minute. + + + + + + + geometric area in inches. + + + + + + + geometric volume in feet. + + + + + + + inch per revolution. + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + + The coordinate system to be used for the position + + + + + + + unchangeable coordinate system that has machine zero as its origin. + + + + + + + coordinate system that represents the working area for a particular + workpiece whose origin is shifted within the `MACHINE` coordinate + system. If the `WORK` coordinates are not currently defined in the + piece of equipment, the `MACHINE` coordinates will be used. + + + + + + + + + Extended tyoe for The reset intervals + + + + + + + + + + The reset intervals + + + + + + + {{term(observation)}} of the {{block(DataItem)}} that is measuring + an action or operation is to be reset upon completion of that action + or operation. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 12-month period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 24-hour period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is not reset and + accumulates for the entire life of the piece of equipment. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset upon + completion of a maintenance event. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a monthly period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset when + power was applied to the piece of equipment after a planned or + unplanned interruption of power has occurred. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a work shift. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 7-day period. + + + + + + + + + The reset intervals + + + + + + + + + The document version + + + + + + + time the file was created. + + + + + + + Indicates that this was a test document + + + + + + + The unique instance identifier of this agent process + + + + + + + The sender of the message + + + + + + + A timestamp in 8601 format of the last update of the Device + information for any device + + + + + + + + indicates if the MTConnect Agent is validating against the normative + model. + + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the data + management within the {{term(agent)}}. + + + + + + + + + The maximum number of assets + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + indicates if the MTConnect Agent is validating against the + normative model. + + + + + + + + + + root entity of an {{term(MTConnectAssets Response Document)}} that + contains the {{term(Asset Information Model)}} of {{block(Asset)}} + types. ![MTConnectAssets](figures/MTConnectAssets.png + "MTConnectAssets"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectAssets)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the + data management within the {{term(agent)}}. + + + + + + + {{block(Assets)}} groups one or more {{block(Asset)}} types. See + {{package(Asset Information Model)}} for more details. + + + + + + + + + A URI reference + + + + + + + + The description of an asset, can be free form text or elements + + + + + + + Any elements + + + + + + + + + {{block(Assets)}} groups one or more {{block(Asset)}} types. See + {{package(Asset Information Model)}} for more details. + + + + + + + + + + {{term(asset)}} that is used by the manufacturing process to perform + tasks. > Note 1 to entry: An {{term(Asset)}} relies upon an + {{term(Device)}} to provide {{termplural(observation)}} and information + about itself and the {{term(Device)}} revises the information to reflect + changes to the {{term(Asset)}} during their interaction. Examples of + {{termplural(Asset)}} are cutting tools, Part Information, Manufacturing + Processes, Fixtures, and Files. > Note 2 to entry: A singular + {{property(Asset::assetId)}} uniquely identifies an {{term(Asset)}} + throughout its lifecycle and is used to track and relate the + {{term(Asset)}} to other {{termplural(Device)}} and entities. > Note + 3 to entry: {{termplural(Asset)}} are temporally associated with a + device and can be removed from the device without damage or alteration + to its primary functions. + + + + + + The unique identifier of the asset + + + + + + + The time asset information was recorded + + + + + + + {{def(EventEnum::DEVICE_UUID)}} + + + + + + + The asset has been marked as removed + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + {{term(asset)}} that is used by the manufacturing process to perform + tasks. > Note 1 to entry: An {{term(Asset)}} relies upon an + {{term(Device)}} to provide {{termplural(observation)}} and information + about itself and the {{term(Device)}} revises the information to reflect + changes to the {{term(Asset)}} during their interaction. Examples of + {{termplural(Asset)}} are cutting tools, Part Information, Manufacturing + Processes, Fixtures, and Files. > Note 2 to entry: A singular + {{property(Asset::assetId)}} uniquely identifies an {{term(Asset)}} + throughout its lifecycle and is used to track and relate the + {{term(Asset)}} to other {{termplural(Device)}} and entities. > Note + 3 to entry: {{termplural(Asset)}} are temporally associated with a + device and can be removed from the device without damage or alteration + to its primary functions. + + + + + + + The interval between adjacent sampleing of data + + + + + + + + The frequency a measurement is sampled + + + + + + + + The constrained value for this data item + + + + + + + + The constrained value for this data item + + + + + + + + The constrained value for this data item + + + + + + + + An idref to the component id + + + + + + + + An idref to the data item id + + + + + + + + The item's reference to the data item or specificatiton + + + + + + + + The name of a related component + + + + + + + + The id reference for the coordinate system associated with this data + item + + + + + + + + An discrete event + + + + + + + + The description of a data item, can be free form text or elements + + + + + + + Any elements + + + + + + + + + The minimum limit on the change in a value + + + + + + + + The measurement sampling type + + + + + + + An event represents a change in state occurs at a point in time. + Note: An event does not occur at predefined frequencies. + + + + + + + A sample is a data point for continuous data items, that is, the + value of a data item at a point in time. + + + + + + + The condition of the device + + + + + + + + + The multiplier for the native value. Conversion divides by this value + + + + + + + + Description + + + + + + + series of sampled data. The data is reported for a specified number + of samples and each sample is reported with a fixed period. + + + + + + + measured value of the sample data. If no + {{property(DataItem::representation)}} is specified for a data item, + the {{property(DataItem::representation)}} **MUST** be determined to + be `VALUE`. + + + + + + + reported value(s) are represented as a set of {{termplural(key-value + pair)}}. Each reported value in the {{term(data set)}} **MUST** have + a unique key. + + + + + + + **DEPRECATED** as {{property(DataItem::representation)}} type in + *MTConnect Version 1.5*. Replaced by the + {{property(DataItem::discrete)}}. + + + + + + + two dimensional set of {{termplural(key-value pair)}} where the + {{block(Entry)}} represents a row, and the value is a set of + {{term(key-value pair)}} {{block(Cell)}} elements. A {{term(table)}} + follows the same behavior as the {{term(data set)}} for change + tracking, clearing, and history. When an {{block(Entry)}} changes, + all {{block(Cell)}} elements update as a single unit following the + behavior of a {{term(data set)}}. > Note: It is best to use + {{block(Variable)}} if the {{block(Cell)}} entities represent + multiple semantic types. Each {{block(Entry)}} in the + {{term(table)}} **MUST** have a unique key. Each {{block(Cell)}} of + each {{block(Entry)}} in the {{term(table)}} **MUST** have a unique + key. See {{block(Representation)}} in {{package(Observation + Information Model)}}, for a description of {{block(Entry)}} and + {{block(Cell)}} elements. + + + + + + + + + The type of filter + + + + + + + new value **MUST NOT** be reported for a data item unless the + measured value has changed from the last reported value by at least + the delta given as the value of this element. The value of + {{block(Filter)}} **MUST** be an absolute value using the same units + as the reported data. + + + + + + + data reported for a data item is provided on a periodic basis. The + `PERIOD` for reporting data is defined in the value of the + {{block(Filter)}}. The value of {{block(Filter)}} **MUST** be an + absolute value reported in seconds representing the time between + reported samples of the value of the data item. + + + + + + + + + + + + + + information reported about a piece of equipment. + + + + + + + + + information reported about a piece of equipment. + + + + + + + identifies the {{block(Component)}}, {{block(DataItem)}}, or + {{block(Composition)}} from which a measured value originates. + + + + + + + {{termplural(organize)}} a set of expected values that can be + reported for a {{block(DataItem)}}. + + + + + + + {{block(Filters)}} groups one or more {{block(Filter)}} entities + associated with the {{block(DataItem)}}. + + + + + + + starting value for a {{block(DataItem)}} as well as the value to be + set for the {{block(DataItem)}} after a reset event. + + + + + + + type of event that may cause a reset to occur. + + + + + + + defines the meaning of {{block(Entry)}} and {{block(Cell)}} entities + when the associated {{property(DataItem::representation)}} is either + `DATA_SET` or `TABLE`. + + + + + + + {{block(Relationships)}} groups one or more + {{block(ConfigurationRelationship)}} types. See + {{package(Relationships)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + unique identifier for the power source. + + + + + + + The type of measurement + + + + + + + The sub type for the measurement + + + + + + + The statistical operation on this data + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + The units as expressed by the machine + + + + + + + The units as expressed by the machine + + + + + + + The category of the data item + + + + + + + Description + + + + + + + The coordinate system reference to a particular coordinate system + + + + + + + The optional composition identifier + + + + + + + Used as the default sample rate for waveforms + + + + + + + Description + + + + + + + The number of significant digits for this data item + + + + + + + Description + + + + + + + + A set of limits for a data item + + + + + + + + + single data value that is expected to be reported for a + {{block(DataItem)}}. {{property(Constraints::Value)}} **MUST + NOT** be used in conjunction with any other + {{block(Constraint)}} elements. + + + + + + + + + numeric lower constraint. + + + + + + + numeric upper constraint. + + + + + + + numeric target or expected value. + + + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + + + {{block(Filters)}} groups one or more {{block(Filter)}} entities + associated with the {{block(DataItem)}}. + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + + + A starting point for a data item + + + + + + + + + + The value element + + + + + + + + + + The filter for the data item + + + + + + + + The type of filter, ABSOLUTE or PERCENT + + + + + + + + + + A native data source + + + + + + + + The optional data item within the source component that provides + the underlying data + + + + + + + The component that is collecting the data associated with this + data item + + + + + + + The optional composition identifier for the source of this data + item + + + + + + + + + + The DataItem Definition + + + + + + + See {{sect(Description)}}. + + + + + + + {{block(EntryDefinitions)}} groups one or more + {{block(EntryDefinition)}} entities. See {{sect(EntryDefinition)}}. + + + + + + + {{block(CellDefinitions)}} groups one or more + {{block(CellDefinition)}} entities. See {{sect(CellDefinition)}}. + + + + + + + + + {{block(EntryDefinitions)}} groups one or more + {{block(EntryDefinition)}} entities. See {{sect(EntryDefinition)}}. + + + + + + + semantic definition of an {{block(Entry)}}. + + + + + + + + + + unique key + + + + + + + The type of measurement + + + + + + + The type of measurement + + + + + + + The sub type for the measurement + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + + semantic definition of an {{block(Entry)}}. + + + + + + + See {{sect(Description)}}. + + + + + + + {{block(CellDefinitions)}} groups one or more + {{block(CellDefinition)}} entities. See {{sect(CellDefinition)}}. + + + + + + + + + + {{block(CellDefinitions)}} groups one or more {{block(CellDefinition)}} + entities. See {{sect(CellDefinition)}}. + + + + + + + semantic definition of a {{block(Cell)}}. + + + + + + + + + semantic definition of a {{block(Cell)}}. + + + + + + + See {{sect(Description)}}. + + + + + + + + + + Organizes DataItemRelationship and SpecificationRelationship + + + + + + + + + + Description + + + + + + identifier of the maintenance activity. + + + + + + + A reference to the related DataItem id. + + + + + + + + Description + + + + + + + How the data items are related + + + + + + + A reference to a DataItem that associates the values with an + external entity + + + + + + + The referenced DataItem provides the id of the effective Coordinate + System + + + + + + + The referenced DataItem provides process limits. + + + + + + + The referenced DataItem provides the observed values. + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(DataItem)}} described by + {{property(DataItemRelationship::type)}}. + + + + + + + + type of the power source. + + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(DataItem)}} described by + {{property(DataItemRelationship::type)}}. + + + + + + + How the data items are related + + + + + + + The referenced DataItem provides process limits. + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(Specification)}} described by + {{property(SpecificationRelationship::type)}} and + {{property(SpecificationRelationship::idRef)}}. + + + + + + + + type of the power source. + + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(Specification)}} described by + {{property(SpecificationRelationship::type)}} and + {{property(SpecificationRelationship::idRef)}}. + + + + + + + An events data + + + + + + + + The item's unique ID that references the data item id from probe + + + + + + + + An Condition code as defined by the component + + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been deprecated in the MTConnect Standard. + + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been extended and cannot be validated. + + + + + + + + indicates if the Observation is verifiable and is in accordance with the + normative definitions within the MTConnect Standard. + + + + + + + observation is not valid against the MTConnect Standard according to + the validation capabilities of the MTConnect Agent. + + + + + + + observation cannot be validated. + + + + + + + observation is valid against the MTConnect Standard. + + + + + + + + + {{block(Streams)}} groups one or more {{block(DeviceStream)}} entities. + See {{package(Observation Information Model)}} for more detail. + + + + + + + Description + + + + + + + + + Description + + + + + + + {{block(ComponentStream)}} {{termplural(organize)}} the + {{block(Observation)}} entities associated with the + {{block(Component)}}. See {{package(Observation Information Model)}} + for the {{block(ComponentStream)}} model. > Note 1 to entry: In + the {{term(XML)}} representation, {{block(ComponentStream)}} + entities **MUST NOT** appear in the {{term(MTConnectDevices Response + Document)}}. > Note 2 to entry: In the {{term(XML)}} + representation, {{block(ComponentStream)}} entities **MUST** appear + only in the {{term(MTConnectStreams Response Document)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + The unque identifier for this device + + + + + + + + {{block(ComponentStream)}} {{termplural(organize)}} the + {{block(Observation)}} entities associated with the + {{block(Component)}}. See {{package(Observation Information Model)}} for + the {{block(ComponentStream)}} model. > Note 1 to entry: In the + {{term(XML)}} representation, {{block(ComponentStream)}} entities **MUST + NOT** appear in the {{term(MTConnectDevices Response Document)}}. > + Note 2 to entry: In the {{term(XML)}} representation, + {{block(ComponentStream)}} entities **MUST** appear only in the + {{term(MTConnectStreams Response Document)}}. + + + + + + + {{block(Samples)}} groups one or more {{block(Sample)}} entities. + See {{sect(Sample)}}. + + + + + + + {{block(Events)}} groups one or more {{block(Event)}} entities. See + {{sect(Event)}}. + + + + + + + Description + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + identifier of the maintenance activity. + + + + + + + The device manufacturer component name + + + + + + + Description + + + + + + + The unque identifier for this component + + + + + + + + {{block(Samples)}} groups one or more {{block(Sample)}} entities. See + {{sect(Sample)}}. + + + + + + + + + + {{block(Events)}} groups one or more {{block(Event)}} entities. See + {{sect(Event)}}. + + + + + + + + + + A collection of conditions + + + + + + + + + + The observation value for indeterminent data + + + + + + + Data is unavailable + + + + + + + + + + The events sequence number + + + + + + + The event subtype corresponding to the measurement subtype + + + + + + + The time the event occurred or recorded + + + + + + + identifier of the maintenance activity. + + + + + + + The unique identifier of the item being produced + + + + + + + The identifier of the sub-element this result is in reference to + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been deprecated in the MTConnect Standard. + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been extended and cannot be validated. + + + + + + + indicates if the Observation is verifiable and is in accordance with + the normative definitions within the MTConnect Standard. + + + + + + + + Integer event value + + + + + + + + Integer event value + + + + + + + + String event value + + + + + + + + DateTime String event value + + + + + + + + A list of axis names + + + + + + + + + + + + A list of axis for an event + + + + + + + + Common floating point event value + + + + + + + + Description + + + + + + + An optional indicator that the event or sample was reset + + + + + + + + Description + + + + + + + An unfaceted string event + + + + + + + + + + + + + + An unfaceted string event + + + + + + + An unfaceted string event + + + + + + + + + + + + + + An unfaceted string event + + + + + + + An unfaceted datetime event + + + + + + + + + + + + + + An unfaceted datetime event + + + + + + + An event with an integer value + + + + + + + + + + + + + + An event with an integer value + + + + + + + An event with an integer value + + + + + + + + + + + + + + An event with an integer value + + + + + + + An event with a three tuple floating point value + + + + + + + + + + + + + + An event with a three tuple floating point value + + + + + + + {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + + {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + Controlled vocabulary for ActuatorState + + + + + + + {{block(Actuator)}} is operating. + + + + + + + {{block(Actuator)}} is not operating. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + The type of asset + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + The type of asset + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + Controlled vocabulary for Availability + + + + + + + data source is active and capable of providing data. + + + + + + + data source is either inactive or not capable of providing data. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + + + + + + {{def(EventEnum::AVAILABILITY)}} + + + + + + + Controlled vocabulary for AxisCoupling + + + + + + + axes are physically connected to each other and operate as a single + unit. + + + + + + + axes are not physically connected to each other but are operating + together in lockstep. + + + + + + + axis is the master of the {{block(CoupledAxes)}}. + + + + + + + axis is a slave to the {{block(CoupledAxes)}}. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + + {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + Controlled vocabulary for AxisInterlock + + + + + + + axis lockout function is activated, power has been removed from the + axis, and the axis is allowed to move freely. + + + + + + + axis lockout function has not been activated, the axis may be + powered, and the axis is capable of being controlled by another + component. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + Controlled vocabulary for AxisState + + + + + + + axis is in its home position. + + + + + + + axis is in motion. + + + + + + + axis has been moved to a fixed position and is being maintained in + that position either electrically or mechanically. Action is + required to release the axis from this position. + + + + + + + axis is stopped. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_STATE)}} + + + + + + + {{def(EventEnum::BLOCK)}} + + + + + + + + + + {{def(EventEnum::BLOCK)}} + + + + + + + {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + + {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + Controlled vocabulary for ChuckInterlock + + + + + + + chuck cannot be unclamped. + + + + + + + chuck can be unclamped. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + Controlled vocabulary for ChuckState + + + + + + + {{block(Chuck)}} is open to the point of a positive confirmation. + + + + + + + {{block(Chuck)}} is closed to the point of a positive confirmation. + + + + + + + {{block(Chuck)}} is not closed to the point of a positive + confirmation and not open to the point of a positive confirmation. + It is in an intermediate position. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::CHUCK_STATE)}} + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + + {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + Controlled vocabulary for ControllerMode + + + + + + + {{block(Controller)}} is configured to automatically execute a + program. + + + + + + + {{block(Controller)}} is not executing an active program. It is + capable of receiving instructions from an external source – + typically an operator. The {{block(Controller)}} executes operations + based on the instructions received from the external source. + + + + + + + operator can enter a series of operations for the + {{block(Controller)}} to perform. The {{block(Controller)}} will + execute this specific series of operations and then stop. + + + + + + + {{block(Controller)}} is operating in a mode that restricts the + active program from processing its next process step without + operator intervention. + + + + + + + {{block(Controller)}} is currently functioning as a programming + device and is not capable of executing an active program. + + + + + + + axes of the device are commanded to stop, but the spindle continues + to function. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + Controlled vocabulary for ControllerModeOverride + + + + + + + {{block(ControllerModeOverride)}} is in the `ON` state and the mode + override is active. + + + + + + + {{block(ControllerModeOverride)}} is in the `OFF` state and the mode + override is inactive. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + + {{def(EventEnum::COUPLED_AXES)}} + + + + + + + {{def(EventEnum::DATE_CODE)}} + + + + + + + + + + {{def(EventEnum::DATE_CODE)}} + + + + + + + {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + + {{def(EventEnum::DEVICE_UUID)}} + + + + + + + Controlled vocabulary for Direction + + + + + + + clockwise rotation using the right-hand rule. + + + + + + + counter-clockwise rotation using the right-hand rule. + + + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::DIRECTION)}} + + + + + + + + + + + + + + {{def(EventEnum::DIRECTION)}} + + + + + + + Controlled vocabulary for DoorState + + + + + + + {{block(Door)}} is open to the point of a positive confirmation. + + + + + + + {{block(Door)}} is closed to the point of a positive confirmation. + + + + + + + {{block(Door)}} is not closed to the point of a positive + confirmation and not open to the point of a positive confirmation. + It is in an intermediate position. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::DOOR_STATE)}} + + + + + + + Controlled vocabulary for EmergencyStop + + + + + + + emergency stop circuit is complete and the piece of equipment, + component, or composition is allowed to operate. + + + + + + + operation of the piece of equipment, component, or composition is + inhibited. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + + + + + + {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + Controlled vocabulary for EndOfBar + + + + + + + {{block(EndOfBar)}} has been reached. + + + + + + + {{block(EndOfBar)}} has not been reached. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + + + + + + {{def(EventEnum::END_OF_BAR)}} + + + + + + + Controlled vocabulary for EquipmentMode + + + + + + + equipment is functioning in the mode designated by the `subType`. + + + + + + + equipment is not functioning in the mode designated by the + `subType`. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + Controlled vocabulary for Execution + + + + + + + {{block(Component)}} is ready to execute instructions. It is + currently idle. + + + + + + + {{block(Component)}} is actively executing an instruction. + + + + + + + {{block(Component)}} suspends the execution of the program due to an + external signal. Action is required to resume execution. + + + + + + + motion of the active axes are commanded to stop at their current + position. + + + + + + + {{block(Component)}} program is not `READY` to execute. + + + + + + + command from the program has intentionally interrupted execution. + The {{block(Component)}} **MAY** have another state that indicates + if the execution is interrupted or the execution ignores the + interrupt instruction. + + + + + + + command from the program has intentionally interrupted execution. + Action is required to resume execution. + + + + + + + program completed execution. + + + + + + + {{block(Component)}} suspends execution while a secondary operation + executes. Execution resumes automatically once the secondary + operation completes. + + + + + + + program has been intentionally optionally stopped using an M01 or + similar code. **DEPRECATED** in *version 1.4* and replaced with + `OPTIONAL_STOP`. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EXECUTION)}} + + + + + + + + + + + + + + {{def(EventEnum::EXECUTION)}} + + + + + + + Controlled vocabulary for FunctionalMode + + + + + + + {{block(Component)}} is currently producing product, ready to + produce product, or its current intended use is to be producing + product. + + + + + + + {{block(Component)}} is not currently producing product. It is being + prepared or modified to begin production of product. + + + + + + + {{block(Component)}} is not currently producing product. Typically, + it has completed the production of a product and is being modified + or returned to a neutral state such that it may then be prepared to + begin production of a different product. + + + + + + + {{block(Component)}} is not currently producing product. It is + currently being repaired, waiting to be repaired, or has not yet + been returned to a normal production status after maintenance has + been performed. + + + + + + + {{block(Component)}} is being used to prove-out a new process, + testing of equipment or processes, or any other active use that does + not result in the production of product. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + {{def(EventEnum::HARDNESS)}} + + + + + + + + + + {{def(EventEnum::HARDNESS)}} + + + + + + + {{def(EventEnum::LINE)}} + + + + + + + + + + {{def(EventEnum::LINE)}} + + + + + + + {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + + {{def(EventEnum::LINE_LABEL)}} + + + + + + + {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + + {{def(EventEnum::LINE_NUMBER)}} + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + + {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + {{def(EventEnum::MESSAGE)}} + + + + + + + + + + {{def(EventEnum::MESSAGE)}} + + + + + + + {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + + {{def(EventEnum::OPERATOR_ID)}} + + + + + + + {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + {{def(EventEnum::PALLET_ID)}} + + + + + + + {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + {{def(EventEnum::PART_COUNT)}} + + + + + + + Controlled vocabulary for PartDetect + + + + + + + part or work piece is detected or is present. + + + + + + + part or work piece is not detected or is not present. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_DETECT)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_DETECT)}} + + + + + + + {{def(EventEnum::PART_ID)}} + + + + + + + + + + {{def(EventEnum::PART_ID)}} + + + + + + + {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + + {{def(EventEnum::PART_NUMBER)}} + + + + + + + {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + + {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + Controlled vocabulary for PathMode + + + + + + + path is operating independently and without the influence of another + path. + + + + + + + path provides information or state values that influences the + operation of other {{block(DataItem)}} of similar type. + + + + + + + physical or logical parts which are not physically connected to each + other but are operating together. + + + + + + + axes associated with the path are mirroring the motion of the + `MASTER` path. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PATH_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::PATH_MODE)}} + + + + + + + Controlled vocabulary for PowerState + + + + + + + source of energy for an entity or the enabling signal providing + permission for the entity to perform its function(s) is present and + active. + + + + + + + source of energy for an entity or the enabling signal providing + permission for the entity to perform its function(s) is not present + or is disconnected. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::POWER_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::POWER_STATE)}} + + + + + + + Controlled vocabulary for PowerStatus + + + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::POWER_STATUS)}} + + + + + + + {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + + {{def(EventEnum::PROCESS_TIME)}} + + + + + + + {{def(EventEnum::PROGRAM)}} + + + + + + + + + + {{def(EventEnum::PROGRAM)}} + + + + + + + {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + Controlled vocabulary for ProgramEdit + + + + + + + {{block(Controller)}} is in the program edit mode. + + + + + + + {{block(Controller)}} is capable of entering the program edit mode + and no function is inhibiting a change to that mode. + + + + + + + {{block(Controller)}} is being inhibited by a function from entering + the program edit mode. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + Controlled vocabulary for ProgramLocationType + + + + + + + managed by the controller. + + + + + + + not managed by the controller. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is not + defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + + {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is not + defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + Controlled vocabulary for RotaryMode + + + + + + + axis is functioning as a spindle. + + + + + + + axis is configured to index. + + + + + + + position of the axis is being interpolated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::ROTARY_MODE)}} + + + + + + + {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command represents a + percentage change to the velocity calculated by a logic or motion + program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + + {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command represents a + percentage change to the velocity calculated by a logic or motion + program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + Controlled vocabulary for SpindleInterlock + + + + + + + power has been removed and the spindle cannot be operated. + + + + + + + spindle has not been deactivated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + + {{def(EventEnum::TOOL_GROUP)}} + + + + + + + {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + {{def(EventEnum::TOOL_ID)}} + + + + + + + {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + + {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + {{def(EventEnum::USER)}} + + + + + + + + + + {{def(EventEnum::USER)}} + + + + + + + {{def(EventEnum::VARIABLE)}} + + + + + + + + + + {{def(EventEnum::VARIABLE)}} + + + + + + + Controlled vocabulary for WaitState + + + + + + + execution is waiting while the equipment is powering up and is not + currently available to begin producing parts or products. + + + + + + + execution is waiting while the equipment is powering down but has + not fully reached a stopped state. + + + + + + + execution is waiting while one or more discrete workpieces are being + loaded. + + + + + + + execution is waiting while one or more discrete workpieces are being + unloaded. + + + + + + + execution is waiting while a tool or tooling is being loaded. + + + + + + + execution is waiting while a tool or tooling is being unloaded. + + + + + + + execution is waiting while material is being loaded. + + + + + + + execution is waiting while material is being unloaded. + + + + + + + execution is waiting while another process is completed before the + execution can resume. + + + + + + + execution is waiting while the equipment is pausing but the piece of + equipment has not yet reached a fully paused state. + + + + + + + execution is waiting while the equipment is resuming the production + cycle but has not yet resumed execution. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::WAIT_STATE)}} When {{property(Execution::result)}} is + not `WAIT`, {{property(Observation::isUnavailable)}} of + {{block(WaitState)}} **MUST** be `true`. + + + + + + + + + + + + + + {{def(EventEnum::WAIT_STATE)}} When {{property(Execution::result)}} is + not `WAIT`, {{property(Observation::isUnavailable)}} of + {{block(WaitState)}} **MUST** be `true`. + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + + {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + + {{def(EventEnum::WORK_OFFSET)}} + + + + + + + {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + + {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + {{def(EventEnum::FIRMWARE)}} + + + + + + + + + + {{def(EventEnum::FIRMWARE)}} + + + + + + + {{def(EventEnum::APPLICATION)}} + + + + + + + + + + {{def(EventEnum::APPLICATION)}} + + + + + + + {{def(EventEnum::LIBRARY)}} + + + + + + + + + + {{def(EventEnum::LIBRARY)}} + + + + + + + {{def(EventEnum::HARDWARE)}} + + + + + + + + + + {{def(EventEnum::HARDWARE)}} + + + + + + + {{def(EventEnum::NETWORK)}} + + + + + + + + + + {{def(EventEnum::NETWORK)}} + + + + + + + rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + + rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + + + + translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + Controlled vocabulary for PartStatus + + + + + + + part conforms to given requirements. + + + + + + + part does not conform to some given requirements. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_STATUS)}} If unique identifier is given, part + status is for that individual. If group identifier is given without a + unique identifier, then the status is assumed to be for the whole group. + + + + + + + + + + + + + + {{def(EventEnum::PART_STATUS)}} If unique identifier is given, part + status is for that individual. If group identifier is given without a + unique identifier, then the status is assumed to be for the whole group. + + + + + + + {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + + {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + {{def(EventEnum::PART_KIND_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_KIND_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + + {{def(EventEnum::ADAPTER_URI)}} + + + + + + + {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + + {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + Controlled vocabulary for ConnectionStatus + + + + + + + no connection at all. + + + + + + + {{term(agent)}} is waiting for a connection request from an + {{term(adapter)}}. + + + + + + + open connection. The normal state for the data transfer phase of the + connection. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + + {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + + {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + + {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + + {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + {{def(EventEnum::PART_GROUP_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_GROUP_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::PART_UNIQUE_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_UNIQUE_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + + {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + + {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + + {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + + {{def(EventEnum::LOAD_COUNT)}} + + + + + + + Controlled vocabulary for PartProcessingState + + + + + + + part occurrence is not actively being processed, but the processing + has not ended. Processing requirements exist that have not yet been + fulfilled. This is the default entry state when the part occurrence + is originally received. In some cases, the part occurrence may + return to this state while it waits for additional processing to be + performed. + + + + + + + part occurrence is actively being processed. + + + + + + + part occurrence is no longer being processed. A general state when + the reason for termination is unknown. + + + + + + + part occurrence has completed processing successfully. + + + + + + + process has been stopped during the processing. The part occurrence + will require special treatment. + + + + + + + processing of the part occurrence has come to a premature end. + + + + + + + terminal state when the part occurrence has been removed from the + equipment by an external entity and it no longer exists at the + equipment. + + + + + + + part occurrence has been skipped for processing on the piece of + equipment. + + + + + + + part occurrence has been processed completely. However, the + processing may have a problem. + + + + + + + part occurrence is waiting for transit. + + + + + + + part occurrence is being transported to its destination. + + + + + + + part occurrence has been placed at its designated destination. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + Controlled vocabulary for ProcessState + + + + + + + device is preparing to execute the process occurrence. + + + + + + + process occurrence is ready to be executed. + + + + + + + process occurrence is actively executing. + + + + + + + process occurrence is now finished. + + + + + + + process occurrence has been stopped and may be resumed. + + + + + + + process occurrence has come to a premature end and cannot be + resumed. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::PROCESS_STATE)}} + + + + + + + Controlled vocabulary for ValveState + + + + + + + {{block(ValveState)}} where flow is allowed and the aperture is + static. > Note: For a binary value, `OPEN` indicates the valve + has the maximum possible aperture. + + + + + + + valve is transitioning from a `CLOSED` state to an `OPEN` state. + + + + + + + {{block(ValveState)}} where flow is not possible, the aperture is + static, and the valve is completely shut. + + + + + + + valve is transitioning from an `OPEN` state to a `CLOSED` state. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::VALVE_STATE)}} + + + + + + + Controlled vocabulary for LockState + + + + + + + mechanism is engaged and preventing the associated + {{block(Component)}} from being opened or operated. + + + + + + + mechanism is disengaged and the associated {{block(Component)}} is + able to be opened or operated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::LOCK_STATE)}} + + + + + + + {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + + {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + + {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + Controlled vocabulary for OperatingMode + + + + + + + automatically execute instructions from a recipe or program. > + Note: Setpoint comes from a recipe. + + + + + + + execute instructions from an external agent or person. > Note 1 + to entry: Valve or switch is manipulated by an agent/person. > + Note 2 to entry: Direct control of the PID output. % of the range: A + user manually sets the % output, not the setpoint. + + + + + + + executes a single instruction from a recipe or program. > Note 1 + to entry: Setpoint is entered and fixed, but the PID is controlling. + > Note 2 to entry: Still goes through the PID control system. + > Note 3 to entry: Manual fixed entry from a recipe. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::OPERATING_MODE)}} + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + + {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + + {{def(EventEnum::FIXTURE_ID)}} + + + + + + + Controlled vocabulary for PartCountType + + + + + + + count is of individual items. + + + + + + + pre-specified group of items. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + + {{def(EventEnum::CLOCK_TIME)}} + + + + + + + {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + + {{def(EventEnum::NETWORK_PORT)}} + + + + + + + {{def(EventEnum::HOST_NAME)}} + + + + + + + + + + {{def(EventEnum::HOST_NAME)}} + + + + + + + Controlled vocabulary for LeakDetect + + + + + + + leak is currently being detected. + + + + + + + leak is currently not being detected. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + + + + + + {{def(EventEnum::LEAK_DETECT)}} + + + + + + + Controlled vocabulary for BatteryState + + + + + + + {{block(Component)}} is at it's maximum rated charge level. + + + + + + + {{block(Component)}}'s charge is increasing. + + + + + + + {{block(Component)}}'s charge is decreasing. + + + + + + + {{block(Component)}} is at it's minimum charge level. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::BATTERY_STATE)}} + + + + + + + {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + + {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + + {{def(EventEnum::SENSOR_STATE)}} + + + + + + + tabular {{def(EventEnum::COMPONENT_DATA)}} If the {{block(Component)}} + multiplicity can be determined, the device model **MUST** use a fixed + set of {{block(Component)}}s. {{block(ComponentData)}} **MUST** provide + a {{block(DataItem)}} {{block(Definition)}}. + + + + + + + + + + tabular {{def(EventEnum::COMPONENT_DATA)}} If the {{block(Component)}} + multiplicity can be determined, the device model **MUST** use a fixed + set of {{block(Component)}}s. {{block(ComponentData)}} **MUST** provide + a {{block(DataItem)}} {{block(Definition)}}. + + + + + + + tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + + tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + + tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + tabular representation of {{def(EventEnum::FEATURE_MEASUREMENT)}} + {{block(FeatureMeasurement)}} **MAY** include a {{term(characteristic)}} + in which case it **MAY** include a `CHARACTERISTIC_STATUS`. + + + + + + + + + + tabular representation of {{def(EventEnum::FEATURE_MEASUREMENT)}} + {{block(FeatureMeasurement)}} **MAY** include a {{term(characteristic)}} + in which case it **MAY** include a `CHARACTERISTIC_STATUS`. + + + + + + + {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, `RADIUS`, + `ANGLE`, `LENGTH`, etc. + + + + + + + + + + {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, `RADIUS`, + `ANGLE`, `LENGTH`, etc. + + + + + + + {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + + {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + + {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + Controlled vocabulary for CharacteristicStatus + + + + + + + measurement is within acceptable tolerances. + + + + + + + measurement is not within acceptable tolerances. + + + + + + + failed, but acceptable constraints achievable by utilizing + additional manufacturing processes. + + + + + + + measurement is indeterminate due to an equipment failure. + + + + + + + measurement cannot be determined. + + + + + + + measurement cannot be evaluated. + + + + + + + nominal provided without tolerance limits. {{cite(QIF 3:2018 + 5.10.2.6)}} + + + + + + + status of measurement cannot be determined. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + Controlled vocabulary for UncertaintyType + + + + + + + {{term(combined standard uncertainty)}}. + + + + + + + {{term(standard uncertainty)}} using arithmetic mean or average the + observations. {{cite(JCGM 100:2008 4.2)}} + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + + {{def(EventEnum::UNCERTAINTY)}} + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + + {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + + {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + + {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + + {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + {{def(EventEnum::THICKNESS)}} + + + + + + + + + + {{def(EventEnum::THICKNESS)}} + + + + + + + {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + + {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + + {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + + {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + + {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + + {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + + {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + Controlled vocabulary for InterfaceState + + + + + + + {{block(Interface)}} is currently operational and performing as + expected. + + + + + + + {{block(Interface)}} is currently not operational. + + + + + + + Value is indeterminate + + + + + + + + + {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + + + + + + {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + Discrete of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + Discrete of {{def(EventEnum::PART_COUNT)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_ID)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + Discrete of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::PALLET_ID)}} + + + + + + + Discrete of {{def(EventEnum::MESSAGE)}} + + + + + + + + + + Discrete of {{def(EventEnum::MESSAGE)}} + + + + + + + Discrete of {{def(EventEnum::BLOCK)}} + + + + + + + + + + Discrete of {{def(EventEnum::BLOCK)}} + + + + + + + The target rate a value can be sampled + + + + + + + + The number of items in the list + + + + + + + + Common floating point sample value + + + + + + + + Common floating point sample value + + + + + + + + Description + + + + + + + The rate the waveform was sampled at, default back to the value given + in the data item + + + + + + + An optional indicator that the event or sample was reset + + + + + + + The statistical operation on this data + + + + + + + The number of seconds since the reset of the statistic + + + + + + + + Description + + + + + + + A sample with a single floating point value + + + + + + + + + + + + + + A sample with a single floating point value + + + + + + + A sample with a three tuple floating point value + + + + + + + + + + + + + + A sample with a three tuple floating point value + + + + + + + The abstract waveform + + + + + + + + The number of samples + + + + + + + + + + The abstract waveform + + + + + + + Description + + + + + + + + + + + + + + Description + + + + + + + {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ACCELERATION)}} + + + + + + + {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + Time series of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + Time series of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE)}} + + + + + + + {{def(SampleEnum::ANGLE)}} + + + + + + + + + + {{def(SampleEnum::ANGLE)}} + + + + + + + Time series of {{def(SampleEnum::ANGLE)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGLE)}} + + + + + + + {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + Time series of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + Time series of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + Time series of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + Time series of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + Time series of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + {{def(SampleEnum::CONCENTRATION)}} + + + + + + + Time series of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + Time series of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + Time series of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + Time series of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + {{def(SampleEnum::DENSITY)}} + + + + + + + + + + {{def(SampleEnum::DENSITY)}} + + + + + + + Time series of {{def(SampleEnum::DENSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::DENSITY)}} + + + + + + + {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + Time series of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + Time series of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + Time series of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + {{def(SampleEnum::FLOW)}} + + + + + + + + + + {{def(SampleEnum::FLOW)}} + + + + + + + Time series of {{def(SampleEnum::FLOW)}} + + + + + + + + + + Time series of {{def(SampleEnum::FLOW)}} + + + + + + + {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + {{def(SampleEnum::FREQUENCY)}} + + + + + + + Time series of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + Time series of {{def(SampleEnum::FREQUENCY)}} + + + + + + + {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + Time series of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + Time series of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + {{def(SampleEnum::LENGTH)}} + + + + + + + + + + {{def(SampleEnum::LENGTH)}} + + + + + + + Time series of {{def(SampleEnum::LENGTH)}} + + + + + + + + + + Time series of {{def(SampleEnum::LENGTH)}} + + + + + + + {{def(SampleEnum::LEVEL)}} + + + + + + + + + + {{def(SampleEnum::LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::LEVEL)}} + + + + + + + {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + Time series of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + Time series of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + {{def(SampleEnum::LOAD)}} + + + + + + + + + + {{def(SampleEnum::LOAD)}} + + + + + + + Time series of {{def(SampleEnum::LOAD)}} + + + + + + + + + + Time series of {{def(SampleEnum::LOAD)}} + + + + + + + {{def(SampleEnum::MASS)}} + + + + + + + + + + {{def(SampleEnum::MASS)}} + + + + + + + Time series of {{def(SampleEnum::MASS)}} + + + + + + + + + + Time series of {{def(SampleEnum::MASS)}} + + + + + + + {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Example + + + + + + + + + + Example + + + + + + + {{def(SampleEnum::PH)}} + + + + + + + + + + {{def(SampleEnum::PH)}} + + + + + + + Time series of {{def(SampleEnum::PH)}} + + + + + + + + + + Time series of {{def(SampleEnum::PH)}} + + + + + + + {{def(SampleEnum::POSITION)}} + + + + + + + + + + {{def(SampleEnum::POSITION)}} + + + + + + + Time series of {{def(SampleEnum::POSITION)}} + + + + + + + + + + Time series of {{def(SampleEnum::POSITION)}} + + + + + + + {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Time series of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + Time series of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Description + + + + + + + + + + Description + + + + + + + Time series of {{def(SampleEnum::PRESSURE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PRESSURE)}} + + + + + + + {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + Time series of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + Time series of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + {{def(SampleEnum::RESISTANCE)}} + + + + + + + Time series of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + Time series of {{def(SampleEnum::RESISTANCE)}} + + + + + + + {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + Time series of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + Time series of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + {{def(SampleEnum::STRAIN)}} + + + + + + + + + + {{def(SampleEnum::STRAIN)}} + + + + + + + Time series of {{def(SampleEnum::STRAIN)}} + + + + + + + + + + Time series of {{def(SampleEnum::STRAIN)}} + + + + + + + {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + {{def(SampleEnum::TEMPERATURE)}} + + + + + + + Time series of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + Time series of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + {{def(SampleEnum::TENSION)}} + + + + + + + + + + {{def(SampleEnum::TENSION)}} + + + + + + + Time series of {{def(SampleEnum::TENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::TENSION)}} + + + + + + + {{def(SampleEnum::TILT)}} + + + + + + + + + + {{def(SampleEnum::TILT)}} + + + + + + + Time series of {{def(SampleEnum::TILT)}} + + + + + + + + + + Time series of {{def(SampleEnum::TILT)}} + + + + + + + {{def(SampleEnum::TORQUE)}} + + + + + + + + + + {{def(SampleEnum::TORQUE)}} + + + + + + + Time series of {{def(SampleEnum::TORQUE)}} + + + + + + + + + + Time series of {{def(SampleEnum::TORQUE)}} + + + + + + + {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::VELOCITY)}} + + + + + + + {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + {{def(SampleEnum::VISCOSITY)}} + + + + + + + Time series of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::VISCOSITY)}} + + + + + + + {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE)}} + + + + + + + {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + Time series of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + Time series of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + {{def(SampleEnum::WATTAGE)}} + + + + + + + Time series of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::WATTAGE)}} + + + + + + + {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::X_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + {{def(SampleEnum::DIAMETER)}} + + + + + + + Time series of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + Time series of {{def(SampleEnum::DIAMETER)}} + + + + + + + {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + + {{def(SampleEnum::ORIENTATION)}} + + + + + + + {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + Time series of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + {{def(SampleEnum::DECELERATION)}} + + + + + + + Time series of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::DECELERATION)}} + + + + + + + {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + The force per unit area measured relative to a vacuum. + + + + + + + + + + The force per unit area measured relative to a vacuum. + + + + + + + Time series of The force per unit area measured relative to a vacuum. + + + + + + + + + + Time series of The force per unit area measured relative to a vacuum. + + + + + + + {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + {{def(SampleEnum::OPENNESS)}} + + + + + + + Time series of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + Time series of {{def(SampleEnum::OPENNESS)}} + + + + + + + {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + {{def(SampleEnum::DEW_POINT)}} + + + + + + + Time series of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEW_POINT)}} + + + + + + + {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + + + + {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + Time series of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + Time series of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + + {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + The description of the Condition + + + + + + + + The device's severity + + + + + + + + Identifier of an individual condition activation provided by a piece of + equipment + + + + + + + + A qualifier for the condition + + + + + + + The value is too high + + + + + + + The value is too low + + + + + + + + + Description + + + + + + + + + type of the power source. + + + + + + + The component specific Notifcation code + + + + + + + The component specific Notifcation code + + + + + + + An optional attribute that helps qualify the condition + + + + + + + The statistical operation on this data + + + + + + + + + + Description + + + + + + + Condition that has transitioned from Normal to either Warning or Fault + + + + + + + + Identifier of an individual condition activation provided by a + piece of equipment + + + + + + + + + + Condition that has transitioned from Normal to either Warning or Fault + + + + + + + The conditon can not be determined. + + + + + + + + + + The conditon can not be determined. + + + + + + + {{term(condition state)}} that indicates operation within specified + limits. + + + + + + + + + + {{term(condition state)}} that indicates operation within specified + limits. + + + + + + + {{term(condition state)}} that requires concern and supervision and may + become hazardous if no action is taken. + + + + + + + + + + {{term(condition state)}} that requires concern and supervision and may + become hazardous if no action is taken. + + + + + + + {{term(condition state)}} that requires intervention to continue + operation to function properly. + + + + + + + + + + {{term(condition state)}} that requires intervention to continue + operation to function properly. + + + + + + + The tool location + + + + + + + + The number referenced in the program for this tool + + + + + + + + The number of times the cutter has been reconditioned + + + + + + + + The code for the connection to the machine + + + + + + + + The tool group associated with the tool + + + + + + + + A speed in RPM or mm/s + + + + + + + + + + A measurement value + + + + + + + + + + The number of location units required to hold this tool + + + + + + + + A measurement value + + + + + + + + The tool identifier + + + + + + + + The number of cutting edges + + + + + + + + The number of additional locations taken by a tool + + + + + + + + The life of the tool in time, wear, or parts + + + + + + + + An identifier for the insert + + + + + + + + A single or range of indexes. A range can be a comma separated set of + individual elements as in "1,2,3,4", or as a inclusive range + of values as in "1-10" or multiple ranges "1-4,6-10" + + + + + + + + + + A minimum value + + + + + + + + A maximum value + + + + + + + + A nominal value + + + + + + + + The material for a cutting item + + + + + + + + A maximum count value + + + + + + + + A application specific code + + + + + + + + A comman delimited list of manufactures + + + + + + + + A relationship + + + + + + + + The format of the definition + + + + + + + The definition will be provided in EXPRESS format + + + + + + + The definition will be provided in XML + + + + + + + The definition will be provided in uninterpreted TEXT + + + + + + + The definition will be provided in an unspecified format + + + + + + + + + The state of the tool. These can be combined to define the complete + cutting tool state + + + + + + + The tool is new + + + + + + + The cutting tool is available for use + + + + + + + The cutting tool is unavailable for use + + + + + + + The cutting tool is assigned to this proces + + + + + + + The cutting tool is NOT assigned to this device + + + + + + + The tool has been measured + + + + + + + An unregisterd state + + + + + + + The tool is being reconditioned + + + + + + + The tool is used + + + + + + + The tool is dead + + + + + + + The tool is currently out being reconditioned or sharpened + + + + + + + The tool is broken + + + + + + + The status of this cutter is undetermined + + + + + + + + + The direction of tool life count + + + + + + + The tool life counts up from the 0 to maximum + + + + + + + The tool life counts down from maximum to 0 + + + + + + + + + The direction of tool life count + + + + + + + The tool life measured in minutes + + + + + + + The tool life measured in parts made + + + + + + + Measurement of tool life in tool wear + + + + + + + + + The type of tool location + + + + + + + A location in a tool magazine. updated + + + + + + + A location in a turret, tool bar, or tool rack. updated + + + + + + + A location within a tool crib. updated + + + + + + + A location associated with a spindle + + + + + + + A location for a tool awaiting transfer from a tool magazine to + spindle or a turret + + + + + + + A location for a tool removed from a spindle or turret and awaiting + return to a tool magazine + + + + + + + A location for a tool awaiting transfer to a tool magazine or turret + from outside of the piece of equipment. + + + + + + + A location for a tool removed from a tool magazine or turret + awaiting transfer to a location outside of the piece of equipment. + + + + + + + A location for a tool that is no longer useable and is awaiting + removal from a tool magazine or turret. + + + + + + + A location associated with an end effector + + + + + + + + + detailed structure of the cutting tool which is static during its + lifecycle. {{cite(ISO 13399)}}. + + + + + + + Any elements + + + + + + + + identifies the expected representation of the enclosed data. + + + + + + + + {{block(Asset)}} that physically removes the material from the workpiece + by shear deformation. + + + + + + + + + See {{sect(Description)}}. + + + + + + + + + detailed structure of the cutting tool which is static + during its lifecycle. {{cite(ISO 13399)}}. + + + + + + + data regarding the application or use of the tool. This data + is provided by various pieces of equipment (i.e. machine + tool, presetter) and statistical process control + applications. Life cycle data will not remain static, but + will change periodically when a tool is used or measured. + + + + + + + + data regarding the application or use of the tool. This data + is provided by various pieces of equipment (i.e. machine tool, + presetter) and statistical process control applications. Life + cycle data will not remain static, but will change + periodically when a tool is used or measured. + + + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + The manufacturer of this asset + + + + + + + {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + {{block(Asset)}} that physically removes the material from the workpiece + by shear deformation. + + + + + + + {{block(Asset)}} that describes the static cutting tool geometries and + nominal values as one would expect from a tool catalog. + + + + + + + + + See {{sect(Description)}}. + + + + + + + + + detailed structure of the cutting tool which is static + during its lifecycle. {{cite(ISO 13399)}}. + + + + + + + data regarding the application or use of the tool. This data + is provided by various pieces of equipment (i.e. machine + tool, presetter) and statistical process control + applications. Life cycle data will not remain static, but + will change periodically when a tool is used or measured. + + + + + + + + data regarding the application or use of the tool. This data + is provided by various pieces of equipment (i.e. machine tool, + presetter) and statistical process control applications. Life + cycle data will not remain static, but will change + periodically when a tool is used or measured. + + + + + + + + + identifier for a class of cutting tools. + + + + + + + + + + {{block(Asset)}} that describes the static cutting tool geometries and + nominal values as one would expect from a tool catalog. + + + + + + + A archetypical cutting tool life cycle definition + + + + + + + number of times the cutter has been reconditioned. + + + + + + + The life of the cutting tool assembly + + + + + + + tool group this tool is assigned in the part program. + + + + + + + number of the tool as referenced in the part program. + + + + + + + constrained process spindle speed for the tool in + revolutions/minute. The {{property(ProcessSpindleSpeed::value)}} + **MAY** contain the nominal process target spindle speed if + available. If {{block(ProcessSpindleSpeed)}} is provided, at least + one value of {{property(ProcessSpindleSpeed::maximum)}}, + {{property(ProcessSpindleSpeed::nominal)}}, or + {{property(ProcessSpindleSpeed::minimum)}} **MUST** be specified. + + + + + + + constrained process feed rate for the tool in mm/s. The + {{property(ProcessFeedRate::value)}} **MAY** contain the nominal + process target feed rate if available. If {{block(ProcessFeedRate)}} + is provided, at least one value of + {{property(ProcessFeedRate::maximum)}}, + {{property(ProcessFeedRate::nominal)}}, or + {{property(ProcessFeedRate::minimum)}} **MUST** be specified. + + + + + + + identifier for the capability to connect any component of the + cutting tool together, except Assembly Items, on the machine side. + Code: `CCMS` + + + + + + + Any additional properties + + + + + + + {{block(Measurements)}} groups one or more {{block(Measurement)}} + subtypes. See {{sect(Measurement)}}. + + + + + + + {{block(CuttingItems)}} groups one or more {{block(CuttingItem)}} + entities. See {{sect(CuttingItem)}} and {{package(Cutting Item)}} + for more detail. + + + + + + + + + data regarding the application or use of the tool. This data is provided + by various pieces of equipment (i.e. machine tool, presetter) and + statistical process control applications. Life cycle data will not + remain static, but will change periodically when a tool is used or + measured. + + + + + + + {{block(CutterStatus)}} provides the status of the assembly and + {{term(organize)}} one or more {{block(Status)}} entities. See + {{sect(Status)}}. The following combinations of {{block(Status)}} + entities **MUST NOT** occur for a {{block(CutterStatus)}}: * `NEW` + **MUST NOT** be used with `USED`, `RECONDITIONED`, or `EXPIRED`. * + `UNKNOWN` **MUST NOT** be used with any other status. * `ALLOCATED` + and `UNALLOCATED` **MUST NOT** be used together. * `AVAILABLE` and + `UNAVAILABLE` **MUST NOT** be used together. * If the tool is + `EXPIRED`, `BROKEN`, or `NOT_REGISTERED` it **MUST NOT** be + `AVAILABLE`. + + + + + + + number of times the cutter has been reconditioned. + + + + + + + Description + + + + + + + tool group this tool is assigned in the part program. + + + + + + + number of the tool as referenced in the part program. + + + + + + + Description + + + + + + + constrained process spindle speed for the tool in + revolutions/minute. The {{property(ProcessSpindleSpeed::value)}} + **MAY** contain the nominal process target spindle speed if + available. If {{block(ProcessSpindleSpeed)}} is provided, at least + one value of {{property(ProcessSpindleSpeed::maximum)}}, + {{property(ProcessSpindleSpeed::nominal)}}, or + {{property(ProcessSpindleSpeed::minimum)}} **MUST** be specified. + + + + + + + constrained process feed rate for the tool in mm/s. The + {{property(ProcessFeedRate::value)}} **MAY** contain the nominal + process target feed rate if available. If {{block(ProcessFeedRate)}} + is provided, at least one value of + {{property(ProcessFeedRate::maximum)}}, + {{property(ProcessFeedRate::nominal)}}, or + {{property(ProcessFeedRate::minimum)}} **MUST** be specified. + + + + + + + identifier for the capability to connect any component of the + cutting tool together, except Assembly Items, on the machine side. + Code: `CCMS` + + + + + + + Any additional properties + + + + + + + {{block(Measurements)}} groups one or more {{block(Measurement)}} + subtypes. See {{sect(Measurement)}}. + + + + + + + {{block(CuttingItems)}} groups one or more {{block(CuttingItem)}} + entities. See {{sect(CuttingItem)}} and {{package(Cutting Item)}} + for more detail. + + + + + + + + + reference information about the {{property(Asset::assetId)}} and/or the + URL of the data source of {{block(CuttingToolArchetype)}}. + + + + + + + + identifies the {{block(Component)}}, {{block(DataItem)}}, or + {{block(Composition)}} from which a measured value originates. + + + + + + + + + + {{block(CutterStatus)}} provides the status of the assembly and + {{term(organize)}} one or more {{block(Status)}} entities. See + {{sect(Status)}}. The following combinations of {{block(Status)}} + entities **MUST NOT** occur for a {{block(CutterStatus)}}: * `NEW` + **MUST NOT** be used with `USED`, `RECONDITIONED`, or `EXPIRED`. * + `UNKNOWN` **MUST NOT** be used with any other status. * `ALLOCATED` and + `UNALLOCATED` **MUST NOT** be used together. * `AVAILABLE` and + `UNAVAILABLE` **MUST NOT** be used together. * If the tool is `EXPIRED`, + `BROKEN`, or `NOT_REGISTERED` it **MUST NOT** be `AVAILABLE`. + + + + + + + status of the cutting tool. + + + + + + + + + Description + + + + + + + + The type of location + + + + + + + number of locations at lower index values from this location. + + + + + + + number of locations at higher index value from this location. + + + + + + + Description + + + + + + + Description + + + + + + + Description + + + + + + + The tool bar associated with a tool + + + + + + + Description + + + + + + + + + + number of times the cutter has been reconditioned. + + + + + + + + The maximum number of times this tool can be reconditioned + + + + + + + + + + constrained process spindle speed for the tool in revolutions/minute. + The {{property(ProcessSpindleSpeed::value)}} **MAY** contain the nominal + process target spindle speed if available. If + {{block(ProcessSpindleSpeed)}} is provided, at least one value of + {{property(ProcessSpindleSpeed::maximum)}}, + {{property(ProcessSpindleSpeed::nominal)}}, or + {{property(ProcessSpindleSpeed::minimum)}} **MUST** be specified. + + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + + + + constrained process feed rate for the tool in mm/s. The + {{property(ProcessFeedRate::value)}} **MAY** contain the nominal process + target feed rate if available. If {{block(ProcessFeedRate)}} is + provided, at least one value of {{property(ProcessFeedRate::maximum)}}, + {{property(ProcessFeedRate::nominal)}}, or + {{property(ProcessFeedRate::minimum)}} **MUST** be specified. + + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + + + + Description + + + + + + + + The number of significant digits + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + The native units for the measurement, if different from units + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + + + + Description + + + + + + + Measurements for both the assembly and the cutting item + + + + + + + + + + Measurements for both the assembly and the cutting item + + + + + + + Measurements for the assembly + + + + + + + + + + Measurements for the assembly + + + + + + + Measurements for the cutting item + + + + + + + + + + Measurements for the cutting item + + + + + + + A collection of assembly measurements + + + + + + + + + + + dimension from the yz-plane to the furthest point of the tool item or + adaptive item measured in the -X direction. + + + + + + + + + + dimension from the yz-plane to the furthest point of the tool item or + adaptive item measured in the -X direction. + + + + + + + total weight of the cutting tool in grams. The force exerted by the mass + of the cutting tool. + + + + + + + + + + total weight of the cutting tool in grams. The force exerted by the mass + of the cutting tool. + + + + + + + distance from the gauge plane or from the end of the shank to the + furthest point on the tool, if a gauge plane does not exist, to the + cutting reference point determined by the main function of the tool. The + {{block(CuttingTool)}} functional length will be the length of the + entire tool, not a single cutting item. Each {{block(CuttingItem)}} can + have an independent {{block(FunctionalLength)}} represented in its + measurements. + + + + + + + + + + distance from the gauge plane or from the end of the shank to the + furthest point on the tool, if a gauge plane does not exist, to the + cutting reference point determined by the main function of the tool. The + {{block(CuttingTool)}} functional length will be the length of the + entire tool, not a single cutting item. Each {{block(CuttingItem)}} can + have an independent {{block(FunctionalLength)}} represented in its + measurements. + + + + + + + largest diameter of the body of a tool item. + + + + + + + + + + largest diameter of the body of a tool item. + + + + + + + distance measured along the X axis from that point of the item closest + to the workpiece, including the cutting item for a tool item but + excluding a protruding locking mechanism for an adaptive item, to either + the front of the flange on a flanged body or the beginning of the + connection interface feature on the machine side for cylindrical or + prismatic shanks. + + + + + + + + + + distance measured along the X axis from that point of the item closest + to the workpiece, including the cutting item for a tool item but + excluding a protruding locking mechanism for an adaptive item, to either + the front of the flange on a flanged body or the beginning of the + connection interface feature on the machine side for cylindrical or + prismatic shanks. + + + + + + + maximum diameter of a circle on which the defined point Pk of each of + the master inserts is located on a tool item. The normal of the machined + peripheral surface points towards the axis of the cutting tool. + + + + + + + + + + maximum diameter of a circle on which the defined point Pk of each of + the master inserts is located on a tool item. The normal of the machined + peripheral surface points towards the axis of the cutting tool. + + + + + + + dimension between two parallel tangents on the outside edge of a flange. + + + + + + + + + + dimension between two parallel tangents on the outside edge of a flange. + + + + + + + maximum engagement of the cutting edge or edges with the workpiece + measured perpendicular to the feed motion. + + + + + + + + + + maximum engagement of the cutting edge or edges with the workpiece + measured perpendicular to the feed motion. + + + + + + + largest length dimension of the cutting tool including the master insert + where applicable. + + + + + + + + + + largest length dimension of the cutting tool including the master insert + where applicable. + + + + + + + dimension of the diameter of a cylindrical portion of a tool item or an + adaptive item that can participate in a connection. + + + + + + + + + + dimension of the diameter of a cylindrical portion of a tool item or an + adaptive item that can participate in a connection. + + + + + + + dimension of the height of the shank. + + + + + + + + + + dimension of the height of the shank. + + + + + + + dimension of the length of the shank. + + + + + + + + + + dimension of the length of the shank. + + + + + + + maximum length of a cutting tool that can be used in a particular + cutting operation including the non-cutting portions of the tool. + + + + + + + + + + maximum length of a cutting tool that can be used in a particular + cutting operation including the non-cutting portions of the tool. + + + + + + + Abstract cutter life + + + + + + + + One of time, part count, or wear + + + + + + + The count up or count down + + + + + + + {{term(condition state)}} that requires concern and supervision + and may become hazardous if no action is taken. + + + + + + + Maximum tool life + + + + + + + The life when the tool is new + + + + + + + + + + A collection of assembly measurements + + + + + + + + + + + diameter of a circle on which the defined point Pk located on this + cutting tool. The normal of the machined peripheral surface points + towards the axis of the cutting tool. + + + + + + + + + + diameter of a circle on which the defined point Pk located on this + cutting tool. The normal of the machined peripheral surface points + towards the axis of the cutting tool. + + + + + + + nominal radius of a rounded corner measured in the X Y-plane. + + + + + + + + + + nominal radius of a rounded corner measured in the X Y-plane. + + + + + + + theoretical length of the cutting edge of a cutting item over sharp + corners. + + + + + + + + + + theoretical length of the cutting edge of a cutting item over sharp + corners. + + + + + + + distance from the basal plane of the tool item to the cutting point. + + + + + + + + + + distance from the basal plane of the tool item to the cutting point. + + + + + + + theoretical sharp point of the cutting tool from which the major + functional dimensions are taken. + + + + + + + + + + theoretical sharp point of the cutting tool from which the major + functional dimensions are taken. + + + + + + + dimension between two parallel tangents on the outside edge of a flange. + + + + + + + + + + dimension between two parallel tangents on the outside edge of a flange. + + + + + + + distance between the cutting reference point and the rear backing + surface of a turning tool or the axis of a boring bar. + + + + + + + + + + distance between the cutting reference point and the rear backing + surface of a turning tool or the axis of a boring bar. + + + + + + + angle between the tool rake plane and a plane parallel to the xy-plane + measured in the tool cutting edge plane + + + + + + + + + + angle between the tool rake plane and a plane parallel to the xy-plane + measured in the tool cutting edge plane + + + + + + + diameter of a circle to which all edges of a equilateral and round + regular insert are tangential. + + + + + + + + + + diameter of a circle to which all edges of a equilateral and round + regular insert are tangential. + + + + + + + angle between the major cutting edge and the same cutting edge rotated + by 180 degrees about the tool axis. + + + + + + + + + + angle between the major cutting edge and the same cutting edge rotated + by 180 degrees about the tool axis. + + + + + + + length of a portion of a stepped tool that is related to a corresponding + cutting diameter measured from the cutting reference point of that + cutting diameter to the point on the next cutting edge at which the + diameter starts to change. + + + + + + + + + + length of a portion of a stepped tool that is related to a corresponding + cutting diameter measured from the cutting reference point of that + cutting diameter to the point on the next cutting edge at which the + diameter starts to change. + + + + + + + angle between a major edge on a step of a stepped tool and the same + cutting edge rotated 180 degrees about its tool axis. + + + + + + + + + + angle between a major edge on a step of a stepped tool and the same + cutting edge rotated 180 degrees about its tool axis. + + + + + + + angle between the tool cutting edge plane and the tool feed plane + measured in a plane parallel the xy-plane. + + + + + + + + + + angle between the tool cutting edge plane and the tool feed plane + measured in a plane parallel the xy-plane. + + + + + + + angle between the tool cutting edge plane and a plane perpendicular to + the tool feed plane measured in a plane parallel the xy-plane. + + + + + + + + + + angle between the tool cutting edge plane and a plane perpendicular to + the tool feed plane measured in a plane parallel the xy-plane. + + + + + + + measure of the length of a wiper edge of a cutting item. + + + + + + + + + + measure of the length of a wiper edge of a cutting item. + + + + + + + angle of the tool with respect to the workpiece for a given process. The + value is application specific. + + + + + + + + + + angle between the driving mechanism locator on a tool item and the main + cutting edge. + + + + + + + + + + The location of the cutting item - not yet restricted. + + + + + + + + {{block(CuttingItems)}} groups one or more {{block(CuttingItem)}} + entities. See {{sect(CuttingItem)}} and {{package(Cutting Item)}} for + more detail. + + + + + + + part of of the tool that physically removes the material from the + workpiece by shear deformation. + + + + + + + + The number of edges + + + + + + + + part of of the tool that physically removes the material from the + workpiece by shear deformation. + + + + + + + See {{sect(Description)}}. + + + + + + + {{block(CutterStatus)}} provides the status of the assembly and + {{term(organize)}} one or more {{block(Status)}} entities. See + {{sect(Status)}}. The following combinations of {{block(Status)}} + entities **MUST NOT** occur for a {{block(CutterStatus)}}: * `NEW` + **MUST NOT** be used with `USED`, `RECONDITIONED`, or `EXPIRED`. * + `UNKNOWN` **MUST NOT** be used with any other status. * `ALLOCATED` + and `UNALLOCATED` **MUST NOT** be used together. * `AVAILABLE` and + `UNAVAILABLE` **MUST NOT** be used together. * If the tool is + `EXPIRED`, `BROKEN`, or `NOT_REGISTERED` it **MUST NOT** be + `AVAILABLE`. + + + + + + + free form description of the location on the cutting tool. For + clarity, the words `FLUTE`, `INSERT`, and `CARTRIDGE` **SHOULD** be + used to assist in noting the location of a {{block(CuttingItem)}}. + {{property(CuttingItem::Locus)}} **MAY** be any free form string, + but **SHOULD** adhere to the following rules: * The location + numbering **SHOULD** start at the furthest {{block(CuttingItem)}} + and work it’s way back to the {{block(CuttingItem)}} closest to the + gauge line. * Flutes **SHOULD** be identified as such using the word + `FLUTE`:. For example: `FLUTE`: 1, `INSERT`: 2 - would indicate the + first flute and the second furthest insert from the end of the tool + on that flute. * Other designations such as `CARTRIDGE` **MAY** be + included, but should be identified using upper case and followed by + a colon (:). + + + + + + + life of a {{block(CuttingItem)}}. + + + + + + + tool group this tool is assigned in the part program. + + + + + + + Any additional properties + + + + + + + {{block(Measurements)}} groups one or more {{block(Measurement)}} + subtypes. See {{sect(Measurement)}}. + + + + + + + + The unique identifier of this insert in this assembly + + + + + + + The manufacturer identifier of this cutting item + + + + + + + The material used for the cutting item + + + + + + + The manufacturer of this asset + + + + + + + + The version of the file + + + + + + + + The mime type of the file + + + + + + + + The size in bytes of the file + + + + + + + + The name of the file + + + + + + + + Extended tyoe for The category of application that will use this file + + + + + + + + + + The category of application that will use this file + + + + + + + Files regarding the fully assembled product + + + + + + + Device related files + + + + + + + Files relating to the handling of material + + + + + + + File relating to equipment maintenance + + + + + + + Files relating to a part + + + + + + + Files related to the manufacturing process + + + + + + + Files related to the quality inspection + + + + + + + Files related to the setup of a process + + + + + + + + + The category of application that will use this file + + + + + + + + Extended tyoe for The type classification of a file + + + + + + + + + + The type classification of a file + + + + + + + Computer aided design files or drawings + + + + + + + Generic data + + + + + + + Documentation regarding a category of file + + + + + + + User instructions regarding the execution of a task + + + + + + + The data related to the history of a machine or process + + + + + + + Machine instructions to perform a process + + + + + + + + + The type classification of a file + + + + + + + + {{block(AbstractFile)}} type that provides information common to all + versions of a file. + + + + + + + + + {{block(FileProperties)}} groups one or more + {{block(FileProperty)}} entities for a {{block(File)}}. See + {{sect(FileProperty)}}. + + + + + + + {{block(FileComments)}} groups one or more + {{block(FileComment)}} entities for a {{block(File)}}. See + {{sect(FileComment)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + The mime type of the file + + + + + + + The classification of this file + + + + + + + The sub classification of this file + + + + + + + + + + {{block(AbstractFile)}} type that provides information common to all + versions of a file. + + + + + + + {{block(FileProperties)}} groups one or more {{block(FileProperty)}} + entities for a {{block(File)}}. See {{sect(FileProperty)}}. + + + + + + + key-value pair providing additional metadata about a + {{block(File)}}. + + + + + + + + + The value of a file property + + + + + + + + key-value pair providing additional metadata about a {{block(File)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + + + + File state + + + + + + + used for processes other than production or otherwise defined. + + + + + + + used for production processes + + + + + + + the content is modified from PRODUCTION or EXPERIMENTAL (Note: To + capture northbound changes. execution -> prod engineering) + + + + + + + + + An X501 Public Key + + + + + + + + A secure hash + + + + + + + + A file time + + + + + + + + {{block(AbstractFile)}} type that provides information about the + {{block(File)}} instance and its {{term(URL)}}. + + + + + + + + + {{block(FileProperties)}} groups one or more + {{block(FileProperty)}} entities for a {{block(File)}}. See + {{sect(FileProperty)}}. + + + + + + + {{block(FileComments)}} groups one or more + {{block(FileComment)}} entities for a {{block(File)}}. See + {{sect(FileComment)}}. + + + + + + + {{term(URL)}} reference to the file location. + + + + + + + secure hash of the file. + + + + + + + public key used to verify the signature. + + + + + + + {{block(Destinations)}} groups one or more + {{block(Destination)}} entities. See {{sect(Destination)}}. + + + + + + + time the file was created. + + + + + + + time the file was modified. + + + + + + + + identifier of the maintenance activity. + + + + + + + The mime type of the file + + + + + + + The classification of this file + + + + + + + The sub classification of this file + + + + + + + The size in bytes + + + + + + + The version identifier + + + + + + + The file state + + + + + + + + + + {{block(AbstractFile)}} type that provides information about the + {{block(File)}} instance and its {{term(URL)}}. + + + + + + + {{term(URL)}} reference to the file location. + + + + + + + + {{term(URL)}} giving the location of the image file. + + + + + + + Description + + + + + + + + + + Organizes file destinations + + + + + + + reference to the target {{block(Device)}} for this {{block(File)}}. + + + + + + + + + The Destination is a reference to the target Device for this File + + + + + + + + + + {{block(FileComments)}} groups one or more {{block(FileComment)}} + entities for a {{block(File)}}. See {{sect(FileComment)}}. + + + + + + + remark or interpretation for human interpretation associated with a + {{block(File)}} or {{block(FileArchetype)}}. + + + + + + + + + the text of the comment + + + + + + + + remark or interpretation for human interpretation associated with a + {{block(File)}} or {{block(FileArchetype)}}. + + + + + + + + The time the comment was made + + + + + + + + + + Extended tyoe for contained QIF Document type as defined in the QIF + Standard. + + + + + + + + + + contained QIF Document type as defined in the QIF Standard. + + + + + + + + + + + + + + + contained QIF Document type as defined in the QIF Standard. + + + + + + + + {{block(Asset)}} that carries the QIF Document. + + + + + + + + + + + + + + + The unique identifier for the material + + + + + + + + + + {{block(Asset)}} that carries the QIF Document. + + + + + + + + + + + + any element + + + + + + + + + The type of the material container. + + + + + + + + The serial number of the material container + + + + + + + + The ISO process type supported by this {{term(raw material)}} + + + + + + + + The type of material. + + + + + + + + The name of the raw feed stock manufacturer. + + + + + + + + The manufacturing date of the raw feed stock from the feed stock + manufacturer. + + + + + + + + The lot code of the raw feed stock from the feed stock manufacturer. + + + + + + + + The ASTM standard code that the material complies with. + + + + + + + + The lot code of the material contained within the material container. + + + + + + + + The form of the material in the material container. + + + + + + + + The date when the material container was first used. + + + + + + + + The date when the material container was last used. + + + + + + + + The amount of material initially placed in the material container when + manufactured. + + + + + + + + The dimension of material initially placed in the material container + when manufactured. + + + + + + + + The quantity of material initially placed in the material container when + manufactured. + + + + + + + + The quantity of material currently contained in the material container + + + + + + + + The dimension of material currently contained in the material container + + + + + + + + The quantity of material currently contained in the material container + + + + + + + + Extended tyoe for form of the {{term(raw material)}}. + + + + + + + + + + form of the {{term(raw material)}}. + + + + + + + + + + + + + + + + + + form of the {{term(raw material)}}. + + + + + + + + material used as the {{block(RawMaterial)}} + + + + + + + manufacturer's lot code of the material. + + + + + + + name of the material manufacturer. + + + + + + + manufacturing date of the material from the material manufacturer. + + + + + + + lot code of the raw feed stock for the material, from the feed stock + manufacturer. + + + + + + + {{term(ASTM)}} standard code that the material complies with. + + + + + + + + The unique identifier for the material + + + + + + + identifier of the maintenance activity. + + + + + + + The type of material. + + + + + + + + {{block(Asset)}} that represents {{term(raw material)}}. + + + + + + + + + form of the {{term(raw material)}}. + + + + + + + {{block(Material)}} has existing usable volume. + + + + + + + manufacturing date of the material from the material + manufacturer. + + + + + + + date {{term(raw material)}} was first used. + + + + + + + date {{term(raw material)}} was last used. + + + + + + + amount of material initially placed in {{term(raw material)}} + when manufactured. + + + + + + + dimension of material initially placed in {{term(raw material)}} + when manufactured. + + + + + + + quantity of material initially placed in {{term(raw material)}} + when manufactured. + + + + + + + amount of material currently in {{term(raw material)}}. + + + + + + + dimension of material currently in {{term(raw material)}}. + + + + + + + quantity of material currently in {{term(raw material)}}. + + + + + + + {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, + materials, or other types of goods. + + + + + + + + identifier of the maintenance activity. + + + + + + + The type of container holding the {{term(raw material)}}. + + + + + + + The ISO process type supported by this {{term(raw material)}}. + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + + {{block(Asset)}} that represents {{term(raw material)}}. + + + + + + + property that determines the characteristic or behavior of an entity. + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + single data value that is expected to be reported for a + {{block(DataItem)}}. {{property(Constraints::Value)}} **MUST NOT** + be used in conjunction with any other {{block(Constraint)}} + elements. + + + + + + + + The identifier of the parameter + + + + + + + identifier of the maintenance activity. + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + + {{block(Parameters)}} groups one or more {{block(Parameter)}} entities. + See {{sect(Parameter)}}. + + + + + + + property that determines the characteristic or behavior of an + entity. + + + + + + + + + set of {{block(Parameter)}}s. + + + + + + + {{block(Parameters)}} groups one or more {{block(Parameter)}} + entities. See {{sect(Parameter)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + + {{block(ParameterSets)}} groups one or more {{block(ParameterSet)}} + entities. See {{sect(ParameterSet)}}. + + + + + + + set of {{block(Parameter)}}s. + + + + + + + + + set of {{block(ParameterSet)}}s that govern the functionality of the + related {{block(Component)}}. + + + + + + + + + {{block(ParameterSets)}} groups one or more + {{block(ParameterSet)}} entities. See {{sect(ParameterSet)}}. + + + + + + + + + + + set of {{block(ParameterSet)}}s that govern the functionality of the + related {{block(Component)}}. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The number of significant digits + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + The native units for the measurement, if different from units + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{block(Measurements)}} groups one or more + {{block(Measurement)}} subtypes. See {{sect(Measurement)}}. + + + + + + + + + + + + + + {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{block(Measurements)}} groups one or more + {{block(Measurement)}} subtypes. See {{sect(Measurement)}}. + + + + + + + + {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/schemas/MTConnectAssets_2.5_1.0.xsd b/schemas/MTConnectAssets_2.5_1.0.xsd new file mode 100644 index 000000000..f0d004744 --- /dev/null +++ b/schemas/MTConnectAssets_2.5_1.0.xsd @@ -0,0 +1,17463 @@ + + + + + + + + root entity of an {{term(MTConnectAssets Response Document)}} that + contains the {{term(Asset Information Model)}} of {{block(Asset)}} + types. ![MTConnectAssets](figures/MTConnectAssets.png + "MTConnectAssets"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectAssets)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + The sender of the message + + + + + + + + The date and time the document was created + + + + + + + + A sequence number + + + + + + + + + + + A debugging flag for testing. + + + + + + + + The instance number of the agent, used for fault tolerance + + + + + + + + + + + The size of the agents buffer + + + + + + + + + + + The time the sample was reported + + + + + + + + The time a sample occurred + + + + + + + + A version number + + + + + + + + A short name for any element + + + + + + + + A universally unique id that uniquely identifies the element for + it's entire life + + + + + + + + A serial number for a piece of equipment + + + + + + + + The measurement source + + + + + + + + A sample rate in milliseconds per sample + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + + An identifier + + + + + + + + The number significant digits + + + + + + + + The item's reference to the Device model composition + + + + + + + + A length of time in seconds + + + + + + + + A flag indicating the item has been removed + + + + + + + + The key for adata set + + + + + + + + A timestamp in 8601 format of the last update of the Device information + for any device + + + + + + + + The unique id of the asset + + + + + + + + An asset type + + + + + + + + The maximum number of assets + + + + + + + + + + + The number of assets + + + + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + The limit of a value + + + + + + + + Common floating point sample value + + + + + + + + + + + + A three dimensional value 'X Y Z' or 'A B C' + + + + + + + + + + + A description + + + + + + + + Extended tyoe for The types of measurements available + + + + + + + + + + The types of measurements available + + + + + + + positive rate of change of velocity. + + + + + + + accumulated time for an activity or event. + + + + + + + strength of electrical current. **DEPRECATED** in *Version 1.6*. + Replaced by `AMPERAGE_AC` and `AMPERAGE_DC`. + + + + + + + angular position. + + + + + + + positive rate of change of angular velocity. + + + + + + + rate of change of angular position. + + + + + + + feedrate of a linear axis. + + + + + + + fluid capacity of an object or container. + + + + + + + geometric capacity of an object or container. + + + + + + + percentage of one component within a mixture of components. + + + + + + + ability of a material to conduct electricity. + + + + + + + speed difference (relative velocity) between the cutting mechanism + and the surface of the workpiece it is operating on. + + + + + + + volumetric mass of a material per unit volume of that material. + + + + + + + rate of change in spatial volume of material deposited in an + additive manufacturing process. + + + + + + + density of the material deposited in an additive manufacturing + process per unit of volume. + + + + + + + mass of the material deposited in an additive manufacturing process. + + + + + + + rate at which a spatial volume of material is deposited in an + additive manufacturing process. + + + + + + + spatial volume of material to be deposited in an additive + manufacturing process. + + + + + + + change in position of an object. + + + + + + + {{block(Wattage)}} used or generated by a component over an interval + of time. + + + + + + + amount of time a piece of equipment or a sub-part of a piece of + equipment has performed specific activities. + + + + + + + amount of a substance remaining compared to the planned maximum + amount of that substance. + + + + + + + rate of flow of a fluid. + + + + + + + number of occurrences of a repeating event per unit time. + + + + + + + position in three-dimensional space. **DEPRECATED** in Version 1.1. + + + + + + + length of an object. + + + + + + + level of a resource. **DEPRECATED** in *Version 1.2*. See + `FILL_LEVEL`. + + + + + + + {{term(force)}} applied to a mass in one direction only. + + + + + + + actual versus the standard rating of a piece of equipment. + + + + + + + mass of an object(s) or an amount of material. + + + + + + + feedrate for the axes, or a single axis, associated with a + {{block(Path)}} component. + + + + + + + feedrate for the axes, or a single axis. + + + + + + + position of a control point associated with a {{block(Controller)}} + or a {{block(Path)}}. + + + + + + + acidity or alkalinity of a solution. + + + + + + + point along an axis in a {{term(cartesian coordinate system)}}. + + + + + + + ratio of real power flowing to a load to the apparent power in that + AC circuit. + + + + + + + force per unit area measured relative to atmospheric pressure. + Commonly referred to as gauge pressure. + + + + + + + amount of time a piece of equipment has performed different types of + activities associated with the process being performed at that piece + of equipment. + + + + + + + degree to which a substance opposes the passage of an electric + current. + + + + + + + rotational speed of a rotary axis. + + + + + + + sound level or sound pressure level relative to atmospheric + pressure. + + + + + + + rotational speed of the rotary axis. **DEPRECATED** in *Version + 1.2*. Replaced by `ROTARY_VELOCITY`. + + + + + + + amount of deformation per unit length of an object when a load is + applied. + + + + + + + degree of hotness or coldness measured on a definite scale. + + + + + + + force that stretches or elongates an object. + + + + + + + angular displacement. + + + + + + + turning force exerted on an object or by an object. + + + + + + + rate of change of position of a {{block(Component)}}. + + + + + + + fluid's resistance to flow. + + + + + + + electrical potential between two points. **DEPRECATED** in *Version + 1.6*. Replaced by `VOLTAGE_AC` and `VOLTAGE_DC`. + + + + + + + apparent power in an electrical circuit, equal to the product of + root-mean-square (RMS) voltage and RMS current (commonly referred to + as VA). + + + + + + + reactive power in an AC electrical circuit (commonly referred to as + VAR). + + + + + + + fluid volume of an object or container. + + + + + + + geometric volume of an object or container. + + + + + + + power flowing through or dissipated by an electrical circuit or + piece of equipment. + + + + + + + electrical current that reverses direction at regular short + intervals. + + + + + + + electric current flowing in one direction only. + + + + + + + electrical potential between two points in an electrical circuit in + which the current periodically reverses direction. + + + + + + + electrical potential between two points in an electrical circuit in + which the current is unidirectional. + + + + + + + dimension of an entity relative to the X direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Y direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Z direction of the referenced + coordinate system. + + + + + + + dimension of a diameter. + + + + + + + angular position of a plane or vector relative to a {{term(cartesian + coordinate system)}} + + + + + + + amount of water vapor present expressed as a percent to reach + saturation at the same temperature. + + + + + + + amount of water vapor expressed in grams per cubic meter. + + + + + + + ratio of the water vapor present over the total weight of the water + vapor and air present expressed as a percent. + + + + + + + average rate of change of values for data items in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + average rate of change of values for assets in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + change of pressure per unit time. + + + + + + + negative rate of change of velocity. + + + + + + + negative rate of change of angular velocity. + + + + + + + force per unit area measured relative to a vacuum. + + + + + + + percentage open where 100% is fully open and 0% is fully closed. + + + + + + + temperature at which moisture begins to condense, corresponding to + saturation for a given absolute humidity. + + + + + + + force relative to earth's gravity. + + + + + + + acceleration relative to Earth's gravity of 9.80665 + `METER/SECOND^2`. + + + + + + + maximum rated charge a battery is capable of maintaining based on + the battery discharging at a specified current over a specified time + period. + + + + + + + value of current being drawn from the {{block(Component)}}. + + + + + + + value of the current being supplied to the {{block(Component)}} for + the purpose of charging. + + + + + + + value of the battery's present capacity expressed as a + percentage of the battery's maximum rated capacity. + + + + + + + difference between actual and commanded position at the end of a + motion. + + + + + + + difference between actual and commanded position at any specific + point in time during a motion. + + + + + + + difference between the commanded encoder/resolver position, and the + actual encoder/resolver position when motion is complete. + + + + + + + angular difference between the commanded encoder/resolver position, + and the actual encoder/resolver position when motion is complete. + + + + + + + difference between the commanded encoder/resolver position and the + actual encoder/resolver position at any specified point in time + during a motion. + + + + + + + angular difference between the commanded encoder/resolver position + and the actual encoder/resolver position at any specified point in + time during a motion. + + + + + + + absolute value of the change in position along a vector. + + + + + + + absolute value of the change in angular position around a vector + + + + + + + point in a {{term(cartesian coordinate system)}}. + + + + + + + set of axes currently associated with a {{block(Path)}} or + {{block(Controller)}}. + + + + + + + operational state of an apparatus for moving or controlling a + mechanism or system. + + + + + + + **DEPRECATED:** Replaced with `CONDITION` category data items in + Version 1.1.0. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been added or + changed. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been removed. + + + + + + + {{term(agent)}}'s ability to communicate with the data source. + + + + + + + describes the way the axes will be associated to each other. This is + used in conjunction with `COUPLED_AXES` to indicate the way they are + interacting. + + + + + + + value of a signal or calculation issued to adjust the feedrate of an + individual linear type axis. + + + + + + + state of the axis lockout function when power has been removed and + the axis is allowed to move freely. + + + + + + + state of a {{block(Linear)}} or {{block(Rotary)}} component + representing an axis. + + + + + + + line of code or command being executed by a {{block(Controller)}} + entity. + + + + + + + total count of the number of blocks of program code that have been + executed since execution started. + + + + + + + state of an interlock function or control logic state intended to + prevent the associated {{block(Chuck)}} component from being + operated. + + + + + + + operating state of a mechanism that holds a part or stock material + during a manufacturing process. It may also represent a mechanism + that holds any other mechanism in place within a piece of equipment. + + + + + + + programmatic code being executed. **DEPRECATED** in *Version 1.1*. + + + + + + + operating state of a mechanism represented by a + {{block(Composition)}} entity. + + + + + + + current mode of the {{block(Controller)}} component. + + + + + + + setting or operator selection that changes the behavior of a piece + of equipment. + + + + + + + set of associated axes. + + + + + + + time and date code associated with a material or other physical + item. + + + + + + + identifier of another piece of equipment that is temporarily + associated with a component of this piece of equipment to perform a + particular function. + + + + + + + direction of motion. + + + + + + + operational state of a {{block(Door)}} component or composition + element. + + + + + + + state of the emergency stop signal for a piece of equipment, + controller path, or any other component or subsystem of a piece of + equipment. + + + + + + + indication of whether the end of a piece of bar stock being feed by + a bar feeder has been reached. + + + + + + + indication that a piece of equipment, or a sub-part of a piece of + equipment, is performing specific types of activities. + + + + + + + operating state of a {{block(Component)}}. + + + + + + + current intended production status of the {{block(Component)}}. + + + + + + + hardness of a material. + + + + + + + current line of code being executed. **DEPRECATED** in *Version + 1.4.0*. + + + + + + + identifier for a {{block(Block)}} of code in a {{block(Program)}}. + + + + + + + position of a block of program code within a control program. + + + + + + + identifier of a material used or consumed in the manufacturing + process. + + + + + + + identifies the layers of material applied to a part or product as + part of an additive manufacturing process. + + + + + + + information to be transferred from a piece of equipment to a client + software application. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + identifier for a pallet. + + + + + + + aggregate count of parts. + + + + + + + indication designating whether a part or work piece has been + detected or is present. + + + + + + + identifier of a part in a manufacturing operation. + + + + + + + identifier of a part or product moving through the manufacturing + process. **DEPRECATED** in *Version 1.7*. `PART_NUMBER` is now a + `subType` of `PART_KIND_ID`. + + + + + + + value of a signal or calculation issued to adjust the feedrate for + the axes associated with a {{block(Path)}} component that may + represent a single axis or the coordinated movement of multiple + axes. + + + + + + + describes the operational relationship between a {{block(Path)}} + entity and another {{block(Path)}} entity for pieces of equipment + comprised of multiple logical groupings of controlled axes or other + logical operations. + + + + + + + indication of the status of the source of energy for an entity to + allow it to perform its intended function or the state of an + enabling signal providing permission for the entity to perform its + functions. + + + + + + + status of the {{block(Component)}}. **DEPRECATED** in *Version + 1.1.0*. + + + + + + + time and date associated with an activity or event. + + + + + + + name of the logic or motion program being executed by the + {{block(Controller)}} component. + + + + + + + comment or non-executable statement in the control program. + + + + + + + indication of the status of the {{block(Controller)}} components + program editing mode. A program may be edited while another is + executed. + + + + + + + name of the program being edited. This is used in conjunction with + {{block(ProgramEdit)}} when in `ACTIVE` state. + + + + + + + non-executable header section of the control program. + + + + + + + {{term(URI)}} for the source file associated with + {{block(Program)}}. + + + + + + + defines whether the logic or motion program defined by + {{block(Program)}} is being executed from the local memory of the + controller or from an outside source. + + + + + + + indication of the nesting level within a control program that is + associated with the code or instructions that is currently being + executed. + + + + + + + current operating mode for a {{block(Rotary)}} type axis. + + + + + + + percentage change to the velocity of the programmed velocity for a + {{block(Rotary)}} axis. + + + + + + + serial number associated with a {{block(Component)}}, + {{block(Asset)}}, or {{block(Device)}}. + + + + + + + indication of the status of the spindle for a piece of equipment + when power has been removed and it is free to rotate. + + + + + + + identifier of an individual tool asset. + + + + + + + identifier for the tool group associated with a specific tool. + Commonly used to designate spare tools. + + + + + + + identifier of the tool currently in use for a given `Path`. + **DEPRECATED** in *Version 1.2.0*. See `TOOL_ASSET_ID`. + + + + + + + identifier assigned by the {{block(Controller)}} component to a + cutting tool when in use by a piece of equipment. + + + + + + + reference to the tool offset variables applied to the active cutting + tool. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + data whose meaning may change over time due to changes in the + operation of a piece of equipment or the process being executed on + that piece of equipment. + + + + + + + indication of the reason that {{block(Execution)}} is reporting a + value of `WAIT`. + + + + + + + identifier for the type of wire used as the cutting mechanism in + Electrical Discharge Machining or similar processes. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. **DEPRECATION WARNING**: Recommend using + `FIXTURE_ID` instead. + + + + + + + reference to offset variables for a work piece or part. + + + + + + + Operating System (OS) of a {{block(Component)}}. + + + + + + + embedded software of a {{block(Component)}} . + + + + + + + application on a {{block(Component)}}. + + + + + + + software library on a {{block(Component)}} + + + + + + + hardware of a {{block(Component)}}. + + + + + + + network details of a {{block(Component)}}. + + + + + + + three space angular displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + three space linear displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + {{term(UUID)}} of new device added to an {{term(MTConnect Agent)}}. + + + + + + + {{term(UUID)}} of a device removed from an {{term(MTConnect + Agent)}}. + + + + + + + {{term(UUID)}} of the device whose {{term(metadata)}} has changed. + + + + + + + status of the connection between an {{term(adapter)}} and an + {{term(agent)}}. + + + + + + + originator’s software version of the {{term(adapter)}}. + + + + + + + {{term(URI)}} of the {{term(adapter)}}. + + + + + + + reference version of the MTConnect Standard supported by the + {{term(adapter)}}. + + + + + + + {{term(attachment)}} between a sensor and an entity. + + + + + + + state or condition of a part. + + + + + + + identifier of a process being executed by the device. + + + + + + + identifier given to link the individual occurrence to a group of + related occurrences, such as a process step in a process plan. + + + + + + + identifier given to link the individual occurrence to a class of + processes or process definition. + + + + + + + identifier given to a collection of individual parts. + + + + + + + identifier given to link the individual occurrence to a class of + parts, typically distinguished by a particular part design. + + + + + + + identifier given to a distinguishable, individual part. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. **DEPRECATION WARNING**. Recommend using + `CONTROL_LIMITS`. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. **DEPRECATION WARNING**. Recommend using + `SPECIFICATION_LIMITS`. + + + + + + + set of limits used to trigger warning or alarm indicators. + **DEPRECATION WARNING**. Recommend using `ALARM_LIMITS`. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, load materials, parts, or other items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, unload materials, parts, or other + items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, transfer materials, parts, or other + items from one location to another. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, activate or be performed. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, deactivate or cease. + + + + + + + accumulation of the number of times a cyclic function has attempted + to, or is planned to attempt to execute. + + + + + + + state of a valve is one of open, closed, or transitioning between + the states. + + + + + + + state or operating mode of a {{block(Lock)}}. + + + + + + + particular condition of the process occurrence at a specific time. + + + + + + + particular condition of the part occurrence at a specific time. + + + + + + + state of {{block(Component)}} or {{block(Composition)}} that + describes the automatic or manual operation of the entity. + + + + + + + {{term(data set)}} of the number of {{termplural(Asset)}} of a given + type for a {{term(Device)}}. + + + + + + + actions or activities to be performed in support of a piece of + equipment. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. + + + + + + + interpretation of `PART_COUNT`. + + + + + + + time provided by a timing device at a specific point in time. + + + + + + + name of the host computer supplying data. + + + + + + + number of the TCP/IP or UDP/IP port for the connection endpoint. + + + + + + + indication designating whether a leak has been detected. + + + + + + + present status of the battery. + + + + + + + {{term(UUID)}} of a {{term(feature)}}. {{cite(ISO 10303 AP + 242/239)}}. + + + + + + + detection result of a sensor. + + + + + + + {{block(Event)}} that represents a {{block(Component)}} where the + {{block(EntryDefinition)}} identifies the {{block(Component)}} and + the {{block(CellDefinition)}}s define the + {{block(Component)}}'s observed {{block(DataItem)}}s. + + + + + + + properties of each addressable work offset. + + + + + + + properties of each addressable tool offset. + + + + + + + assessing elements of a {{term(feature)}}. + + + + + + + {{term(UUID)}} of the {{term(characteristic)}}. + + + + + + + class of measurement being performed. {{cite(QIF 3:2018 Section + 6.3)}} + + + + + + + measurement based on the measurement type. + + + + + + + engineering units of the measurement. + + + + + + + pass/fail result of the measurement. + + + + + + + method used to compute {{term(standard uncertainty)}}. + + + + + + + {{term(uncertainty)}} specified by {{block(UncertaintyType)}}. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. + + + + + + + set of limits used to trigger warning or alarm indicators. + + + + + + + references the {{block(CuttingToolLifeCycle)}} + {{block(CuttingItem)}} index related to the + {{property(CuttingItem::indices)}} of the currently active cutting + tool edge. + + + + + + + structured information that allows the unambiguous determination of + an object for purposes of identification and location. {{cite(ISO + 19160-4:2017)}} + + + + + + + active energy source for the {{block(Component)}}. + + + + + + + textual description of the location of an object or activity. + + + + + + + dimension between two surfaces of an object, usually the dimension + of smallest measure, for example an additive layer, or a depth of + cut. + + + + + + + absolute geographic location defined by two coordinates, longitude + and latitude and an elevation. + + + + + + + indication that the piece of equipment has experienced a + communications failure. + + + + + + + indication that the value of the data associated with a measured + value or a calculation is outside of an expected range. + + + + + + + indication that an error occurred in the logic program or + programmable logic controller (PLC) associated with a piece of + equipment. + + + + + + + indication that an error occurred in the motion program associated + with a piece of equipment. + + + + + + + general purpose indication associated with an electronic component + of a piece of equipment or a controller that represents a fault that + is not associated with the operator, program, or hardware. + + + + + + + indication of a fault associated with an actuator. + + + + + + + operational state of an {{block(Interface)}}. + + + + + + + operating state of the service to advance material or feed product + to a piece of equipment from a continuous or bulk source. + + + + + + + operating state of the service to change the type of material or + product being loaded or fed to a piece of equipment. + + + + + + + operating state of the service to remove or retract material or + product. + + + + + + + operating state of the service to change the part or product + associated with a piece of equipment to a different part or product. + + + + + + + operating state of the service to load a piece of material or + product. + + + + + + + operating state of the service to unload a piece of material or + product. + + + + + + + operating state of the service to open a chuck. + + + + + + + operating state of the service to open a door. + + + + + + + operating state of the service to close a chuck. + + + + + + + operating state of the service to close a door. + + + + + + + A user variable + + + + + + + + + The types of measurements available + + + + + + + + Extended tyoe for The sub-types for a measurement + + + + + + + + + + The sub-types for a measurement + + + + + + + relating to or derived in the simplest manner from the fundamental + units or measurements. + + + + + + + indication of the operating state of a mechanism. + + + + + + + measured or reported value of an {{term(observation)}}. + + + + + + + all actions, items, or activities being counted independent of the + outcome. + + + + + + + measurement of alternating voltage or current. If not specified + further in statistic, defaults to RMS voltage. **DEPRECATED** in + *Version 1.6*. + + + + + + + A-Scale weighting factor on the frequency scale. + + + + + + + when multiple locations on a piece of bar stock being feed by a bar + feeder are referenced as the indication of whether the end of that + piece of bar stock has been reached. + + + + + + + actions, items, or activities being counted that do not conform to + specification or expectation. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + B-Scale weighting factor on the frequency scale. + + + + + + + directive value including adjustments such as an offset or + overrides. + + + + + + + amount of material consumed from an object or container during a + manufacturing process. + + + + + + + state of the enabling signal or control logic that enables or + disables the function or operation of the entity. + + + + + + + C-Scale weighting factor on the frequency scale. + + + + + + + elapsed time of a temporary halt of action. + + + + + + + DC current or voltage. **DEPRECATED** in *Version 1.6*. + + + + + + + setting or operator selection used to execute a test mode to confirm + the execution of machine functions. + + + + + + + D-Scale weighting factor on the frequency scale. + + + + + + + relating to the expiration or end of useful life for a material or + other physical item. + + + + + + + relating to the first use of a material or other physical item. + + + + + + + actions, items, or activities being counted that conform to + specification or expectation. + + + + + + + relating to or derived from the last {{term(observation)}}. + + + + + + + relating to momentary activation of a function or a movement. + **DEPRECATION WARNING**: May be deprecated in the future. + + + + + + + indication of the position of a mechanism that may move in a lateral + direction. + + + + + + + scale to measure the elasticity of a surface. + + + + + + + reference to a length type tool offset variable. + + + + + + + state of the power source. + + + + + + + direction of motion of a linear motion. + + + + + + + indication that the subparts of a piece of equipment are under load. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + relating to the primary logic or motion program currently being + executed. + + + + + + + relating to maintenance on the piece of equipment. + + + + + + + indication of the state of an operator controlled interlock that can + inhibit the ability to initiate an unclamp action of an + electronically controlled chuck. + + + + + + + related to the production of a material or other physical item. + + + + + + + maximum value. + + + + + + + minimum value. + + + + + + + scale to measure the resistance to scratching of a surface. + + + + + + + indication of the open or closed state of a mechanism. + + + + + + + no weighting factor on the frequency scale. + + + + + + + piece of equipment that is powered or performing any activity. + + + + + + + relating to the person currently responsible for operating the piece + of equipment. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + overridden value. + + + + + + + piece of equipment is powered and functioning or + {{block(Component)}} that are required to remain on are powered. + + + + + + + main or principle. + + + + + + + position provided by a measurement probe. **DEPRECATION WARNING**: + May be deprecated in the future. + + + + + + + relating to production of a part or product on a piece of equipment. + + + + + + + directive value without offsets and adjustments. + + + + + + + reference to a radial type tool offset variable. + + + + + + + performing an operation faster or in less time than nominal rate. + + + + + + + remaining measure or count of an action, object or activity. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + direction of a rotary motion using the right hand rule convention. + + + + + + + identity of a control program that is used to specify the order of + execution of other programs. + + + + + + + relating to the preparation of a piece of equipment for production + or restoring the piece of equipment to a neutral state after + production. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + standard measure of an object or an action. + + + + + + + boundary when an activity or an event commences. + + + + + + + indication of the activation state of a mechanism represented by a + {{block(Composition)}}. + + + + + + + goal of the operation or process. + + + + + + + relating to the end or completion of an activity or event. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + remaining usable measure of an object or action. + + + + + + + indication of the position of a mechanism that may move in a + vertical direction. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + piece of equipment performing any activity, the equipment is active + and performing a function under load or not. + + + + + + + IPV4 network address of the {{block(Component)}}. + + + + + + + IPV6 network address of the {{block(Component)}}. + + + + + + + Gateway for the {{block(Component)}} network. + + + + + + + SubNet mask for the {{block(Component)}} network. + + + + + + + layer2 Virtual Local Network (VLAN) ID for the {{block(Component)}} + network. + + + + + + + Media Access Control Address. The unique physical address of the + network hardware. + + + + + + + identifies whether the connection type is wireless. + + + + + + + license code to validate or activate the hardware or software. + + + + + + + version of the hardware or software. + + + + + + + date the hardware or software was released for general use. + + + + + + + date the hardware or software was installed. + + + + + + + corporate identity for the maker of the hardware or software. + + + + + + + universally unique identifier as specified in ISO 11578 or RFC 4122. + + + + + + + serial number that uniquely identifies a specific part. + + + + + + + material that is used to produce parts. + + + + + + + group of parts tracked as a lot. + + + + + + + group of parts produced in a batch. + + + + + + + material heat number. + + + + + + + particular part design or model. + + + + + + + group of parts having similarities in geometry, manufacturing + process, and/or functions. + + + + + + + word or set of words by which a part is known, addressed, or + referred to. + + + + + + + step in the process plan that this occurrence corresponds to. + + + + + + + process plan that a process occurrence belongs to. + + + + + + + authorization of a process occurrence. + + + + + + + word or set of words by which a process being executed (process + occurrence) by the device is known, addressed, or referred to. + + + + + + + reference to a ISO 10303 Executable. + + + + + + + associated with the completion of an activity or event. + + + + + + + relating to logic or motion program currently executing. + + + + + + + actions or activities that were attempted , but failed to complete + or resulted in an unexpected or unacceptable outcome. + + + + + + + actions or activities that were attempted, but terminated before + they could be completed. + + + + + + + boundary when an activity or an event terminates. + + + + + + + amount discarded. + + + + + + + amount included in the {{term(part)}}. + + + + + + + {{term(request)}} by an {{block(Interface)}} for a task. + + + + + + + {{term(response)}} by an {{block(Interface)}} to a {{term(request)}} + for a task. + + + + + + + phase or segment of a recipe or program. + + + + + + + phase of a recipe process. + + + + + + + process as part of product production; can be a subprocess of a + larger process. + + + + + + + step of a discrete manufacturing process. + + + + + + + observed as a binary data type. + + + + + + + observed as a boolean data type. + + + + + + + observed as a set containing a restricted number of discrete values + where each discrete value is named and unique. {{cite(ISO + 21961:2003, 013)}} + + + + + + + indicated by the presence or existence of something. + + + + + + + model info of the hardware or software. + + + + + + + + + The sub-types for a measurement + + + + + + + + Extended tyoe for Statistical operations on data + + + + + + + + + + Statistical operations on data + + + + + + + mathematical average value calculated for the data item during the + calculation period. + + + + + + + **DEPRECATED** in *Version 1.6*. ~~A measure of the + "peakedness" of a probability distribution; i.e., the + shape of the distribution curve.~~ + + + + + + + maximum or peak value recorded for the data item during the + calculation period. + + + + + + + middle number of a series of numbers. + + + + + + + minimum value recorded for the data item during the calculation + period. + + + + + + + number in a series of numbers that occurs most often. + + + + + + + difference between the maximum and minimum value of a data item + during the calculation period. Also represents Peak-to-Peak + measurement in a waveform. + + + + + + + mathematical Root Mean Square (RMS) value calculated for the data + item during the calculation period. + + + + + + + statistical Standard Deviation value calculated for the data item + during the calculation period. + + + + + + + + + Statistical operations on data + + + + + + + + Extended tyoe for same as {{property(DataItem::units)}}. See + {{package(Device Information Model)}}. + + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + + Extended tyoe for The units supported for the source equipment that can + be converted into MTC Units. + + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + measure of viscosity. + + + + + + + rotational velocity in degrees per minute. + + + + + + + temperature in Fahrenheit. + + + + + + + feet. + + + + + + + feet per minute. + + + + + + + feet per second. + + + + + + + acceleration in feet per second squared. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in feet. + + + + + + + gallons per minute. + + + + + + + measurement of time in hours. + + + + + + + inches. + + + + + + + inches per minute. + + + + + + + inches per second. + + + + + + + acceleration in inches per second squared. + + + + + + + measure of torque in inch pounds. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in inches. + + + + + + + measurement of temperature. + + + + + + + measurement in kilowatt. + + + + + + + kilowatt hours which is 3.6 mega joules. + + + + + + + measurement of rate of flow of a fluid. + + + + + + + velocity in millimeters per minute. + + + + + + + measurement of time in minutes. + + + + + + + unsupported unit. + + + + + + + US pounds. + + + + + + + pressure in pounds per square inch (PSI). + + + + + + + angle in radians. + + + + + + + velocity in radians per minute. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + pressure in Bar. + + + + + + + pressure in Torr. + + + + + + + pressure in Millimeter of Mercury (mmHg). + + + + + + + pascal per minute. + + + + + + + $$MASS\times GRAVITATIONAL_ACCELERATION$$ (g) given in + `METER/SECOND^2`. + + + + + + + acceleration relative to earth's gravity given in + `METER/SECOND^2`. > Note 1 to entry: At different points on + Earth's surface, the free-fall acceleration ranges from 9.764 + to 9.834 m/s2 (Wikipedia: Gravitational Acceleration). The constant + can be customized depending on the location in the universe. > + Note 2 to entry: In the standard, it is assumed that Earth's + average value of gravitational acceleration is 9.90665 m/s2. + + + + + + + electric charge in ampere hour. + + + + + + + change of geometric volume in cubic foot per hour. + + + + + + + change of geometric volume in cubic foot per minute. + + + + + + + geometric area in inches. + + + + + + + geometric volume in feet. + + + + + + + inch per revolution. + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + + The coordinate system to be used for the position + + + + + + + unchangeable coordinate system that has machine zero as its origin. + + + + + + + coordinate system that represents the working area for a particular + workpiece whose origin is shifted within the `MACHINE` coordinate + system. If the `WORK` coordinates are not currently defined in the + piece of equipment, the `MACHINE` coordinates will be used. + + + + + + + + + Extended tyoe for The reset intervals + + + + + + + + + + The reset intervals + + + + + + + {{term(observation)}} of the {{block(DataItem)}} that is measuring + an action or operation is to be reset upon completion of that action + or operation. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 12-month period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 24-hour period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is not reset and + accumulates for the entire life of the piece of equipment. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset upon + completion of a maintenance event. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a monthly period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset when + power was applied to the piece of equipment after a planned or + unplanned interruption of power has occurred. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a work shift. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 7-day period. + + + + + + + + + The reset intervals + + + + + + + + + The document version + + + + + + + time the file was created. + + + + + + + Indicates that this was a test document + + + + + + + The unique instance identifier of this agent process + + + + + + + The sender of the message + + + + + + + A timestamp in 8601 format of the last update of the Device + information for any device + + + + + + + + indicates if the MTConnect Agent is validating against the normative + model. + + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the data + management within the {{term(agent)}}. + + + + + + + + + The maximum number of assets + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + indicates if the MTConnect Agent is validating against the + normative model. + + + + + + + + + + root entity of an {{term(MTConnectAssets Response Document)}} that + contains the {{term(Asset Information Model)}} of {{block(Asset)}} + types. ![MTConnectAssets](figures/MTConnectAssets.png + "MTConnectAssets"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectAssets)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the + data management within the {{term(agent)}}. + + + + + + + {{block(Assets)}} groups one or more {{block(Asset)}} types. See + {{package(Asset Information Model)}} for more details. + + + + + + + + + A URI reference + + + + + + + + The description of an asset, can be free form text or elements + + + + + + + Any elements + + + + + + + + + {{block(Assets)}} groups one or more {{block(Asset)}} types. See + {{package(Asset Information Model)}} for more details. + + + + + + + + + + {{term(asset)}} that is used by the manufacturing process to perform + tasks. > Note 1 to entry: An {{term(Asset)}} relies upon an + {{term(Device)}} to provide {{termplural(observation)}} and information + about itself and the {{term(Device)}} revises the information to reflect + changes to the {{term(Asset)}} during their interaction. Examples of + {{termplural(Asset)}} are cutting tools, Part Information, Manufacturing + Processes, Fixtures, and Files. > Note 2 to entry: A singular + {{property(Asset::assetId)}} uniquely identifies an {{term(Asset)}} + throughout its lifecycle and is used to track and relate the + {{term(Asset)}} to other {{termplural(Device)}} and entities. > Note + 3 to entry: {{termplural(Asset)}} are temporally associated with a + device and can be removed from the device without damage or alteration + to its primary functions. + + + + + + The unique identifier of the asset + + + + + + + The time asset information was recorded + + + + + + + {{def(EventEnum::DEVICE_UUID)}} + + + + + + + The asset has been marked as removed + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + {{term(asset)}} that is used by the manufacturing process to perform + tasks. > Note 1 to entry: An {{term(Asset)}} relies upon an + {{term(Device)}} to provide {{termplural(observation)}} and information + about itself and the {{term(Device)}} revises the information to reflect + changes to the {{term(Asset)}} during their interaction. Examples of + {{termplural(Asset)}} are cutting tools, Part Information, Manufacturing + Processes, Fixtures, and Files. > Note 2 to entry: A singular + {{property(Asset::assetId)}} uniquely identifies an {{term(Asset)}} + throughout its lifecycle and is used to track and relate the + {{term(Asset)}} to other {{termplural(Device)}} and entities. > Note + 3 to entry: {{termplural(Asset)}} are temporally associated with a + device and can be removed from the device without damage or alteration + to its primary functions. + + + + + + + The interval between adjacent sampleing of data + + + + + + + + The frequency a measurement is sampled + + + + + + + + The constrained value for this data item + + + + + + + + The constrained value for this data item + + + + + + + + The constrained value for this data item + + + + + + + + An idref to the component id + + + + + + + + An idref to the data item id + + + + + + + + The item's reference to the data item or specificatiton + + + + + + + + The name of a related component + + + + + + + + The id reference for the coordinate system associated with this data + item + + + + + + + + An discrete event + + + + + + + + The description of a data item, can be free form text or elements + + + + + + + Any elements + + + + + + + + + The minimum limit on the change in a value + + + + + + + + The measurement sampling type + + + + + + + An event represents a change in state occurs at a point in time. + Note: An event does not occur at predefined frequencies. + + + + + + + A sample is a data point for continuous data items, that is, the + value of a data item at a point in time. + + + + + + + The condition of the device + + + + + + + + + The multiplier for the native value. Conversion divides by this value + + + + + + + + Description + + + + + + + series of sampled data. The data is reported for a specified number + of samples and each sample is reported with a fixed period. + + + + + + + measured value of the sample data. If no + {{property(DataItem::representation)}} is specified for a data item, + the {{property(DataItem::representation)}} **MUST** be determined to + be `VALUE`. + + + + + + + reported value(s) are represented as a set of {{termplural(key-value + pair)}}. Each reported value in the {{term(data set)}} **MUST** have + a unique key. + + + + + + + **DEPRECATED** as {{property(DataItem::representation)}} type in + *MTConnect Version 1.5*. Replaced by the + {{property(DataItem::discrete)}}. + + + + + + + two dimensional set of {{termplural(key-value pair)}} where the + {{block(Entry)}} represents a row, and the value is a set of + {{term(key-value pair)}} {{block(Cell)}} elements. A {{term(table)}} + follows the same behavior as the {{term(data set)}} for change + tracking, clearing, and history. When an {{block(Entry)}} changes, + all {{block(Cell)}} elements update as a single unit following the + behavior of a {{term(data set)}}. > Note: It is best to use + {{block(Variable)}} if the {{block(Cell)}} entities represent + multiple semantic types. Each {{block(Entry)}} in the + {{term(table)}} **MUST** have a unique key. Each {{block(Cell)}} of + each {{block(Entry)}} in the {{term(table)}} **MUST** have a unique + key. See {{block(Representation)}} in {{package(Observation + Information Model)}}, for a description of {{block(Entry)}} and + {{block(Cell)}} elements. + + + + + + + + + The type of filter + + + + + + + new value **MUST NOT** be reported for a data item unless the + measured value has changed from the last reported value by at least + the delta given as the value of this element. The value of + {{block(Filter)}} **MUST** be an absolute value using the same units + as the reported data. + + + + + + + data reported for a data item is provided on a periodic basis. The + `PERIOD` for reporting data is defined in the value of the + {{block(Filter)}}. The value of {{block(Filter)}} **MUST** be an + absolute value reported in seconds representing the time between + reported samples of the value of the data item. + + + + + + + + + + + + + + information reported about a piece of equipment. + + + + + + + + + information reported about a piece of equipment. + + + + + + + identifies the {{block(Component)}}, {{block(DataItem)}}, or + {{block(Composition)}} from which a measured value originates. + + + + + + + {{termplural(organize)}} a set of expected values that can be + reported for a {{block(DataItem)}}. + + + + + + + {{block(Filters)}} groups one or more {{block(Filter)}} entities + associated with the {{block(DataItem)}}. + + + + + + + starting value for a {{block(DataItem)}} as well as the value to be + set for the {{block(DataItem)}} after a reset event. + + + + + + + type of event that may cause a reset to occur. + + + + + + + defines the meaning of {{block(Entry)}} and {{block(Cell)}} entities + when the associated {{property(DataItem::representation)}} is either + `DATA_SET` or `TABLE`. + + + + + + + {{block(Relationships)}} groups one or more + {{block(ConfigurationRelationship)}} types. See + {{package(Relationships)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + unique identifier for the power source. + + + + + + + The type of measurement + + + + + + + The sub type for the measurement + + + + + + + The statistical operation on this data + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + The units as expressed by the machine + + + + + + + The units as expressed by the machine + + + + + + + The category of the data item + + + + + + + Description + + + + + + + The coordinate system reference to a particular coordinate system + + + + + + + The optional composition identifier + + + + + + + Used as the default sample rate for waveforms + + + + + + + Description + + + + + + + The number of significant digits for this data item + + + + + + + Description + + + + + + + + A set of limits for a data item + + + + + + + + + single data value that is expected to be reported for a + {{block(DataItem)}}. {{property(Constraints::Value)}} **MUST + NOT** be used in conjunction with any other + {{block(Constraint)}} elements. + + + + + + + + + numeric lower constraint. + + + + + + + numeric upper constraint. + + + + + + + numeric target or expected value. + + + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + + + {{block(Filters)}} groups one or more {{block(Filter)}} entities + associated with the {{block(DataItem)}}. + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + + + A starting point for a data item + + + + + + + + + + The value element + + + + + + + + + + The filter for the data item + + + + + + + + The type of filter, ABSOLUTE or PERCENT + + + + + + + + + + A native data source + + + + + + + + The optional data item within the source component that provides + the underlying data + + + + + + + The component that is collecting the data associated with this + data item + + + + + + + The optional composition identifier for the source of this data + item + + + + + + + + + + The DataItem Definition + + + + + + + See {{sect(Description)}}. + + + + + + + {{block(EntryDefinitions)}} groups one or more + {{block(EntryDefinition)}} entities. See {{sect(EntryDefinition)}}. + + + + + + + {{block(CellDefinitions)}} groups one or more + {{block(CellDefinition)}} entities. See {{sect(CellDefinition)}}. + + + + + + + + + {{block(EntryDefinitions)}} groups one or more + {{block(EntryDefinition)}} entities. See {{sect(EntryDefinition)}}. + + + + + + + semantic definition of an {{block(Entry)}}. + + + + + + + + + + unique key + + + + + + + The type of measurement + + + + + + + The type of measurement + + + + + + + The sub type for the measurement + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + + semantic definition of an {{block(Entry)}}. + + + + + + + See {{sect(Description)}}. + + + + + + + {{block(CellDefinitions)}} groups one or more + {{block(CellDefinition)}} entities. See {{sect(CellDefinition)}}. + + + + + + + + + + {{block(CellDefinitions)}} groups one or more {{block(CellDefinition)}} + entities. See {{sect(CellDefinition)}}. + + + + + + + semantic definition of a {{block(Cell)}}. + + + + + + + + + semantic definition of a {{block(Cell)}}. + + + + + + + See {{sect(Description)}}. + + + + + + + + + + Organizes DataItemRelationship and SpecificationRelationship + + + + + + + + + + Description + + + + + + identifier of the maintenance activity. + + + + + + + A reference to the related DataItem id. + + + + + + + + Description + + + + + + + How the data items are related + + + + + + + A reference to a DataItem that associates the values with an + external entity + + + + + + + The referenced DataItem provides the id of the effective Coordinate + System + + + + + + + The referenced DataItem provides process limits. + + + + + + + The referenced DataItem provides the observed values. + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(DataItem)}} described by + {{property(DataItemRelationship::type)}}. + + + + + + + + type of the power source. + + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(DataItem)}} described by + {{property(DataItemRelationship::type)}}. + + + + + + + How the data items are related + + + + + + + The referenced DataItem provides process limits. + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(Specification)}} described by + {{property(SpecificationRelationship::type)}} and + {{property(SpecificationRelationship::idRef)}}. + + + + + + + + type of the power source. + + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(Specification)}} described by + {{property(SpecificationRelationship::type)}} and + {{property(SpecificationRelationship::idRef)}}. + + + + + + + An events data + + + + + + + + The item's unique ID that references the data item id from probe + + + + + + + + An Condition code as defined by the component + + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been deprecated in the MTConnect Standard. + + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been extended and cannot be validated. + + + + + + + + indicates if the Observation is verifiable and is in accordance with the + normative definitions within the MTConnect Standard. + + + + + + + observation is not valid against the MTConnect Standard according to + the validation capabilities of the MTConnect Agent. + + + + + + + observation cannot be validated. + + + + + + + observation is valid against the MTConnect Standard. + + + + + + + + + {{block(Streams)}} groups one or more {{block(DeviceStream)}} entities. + See {{package(Observation Information Model)}} for more detail. + + + + + + + Description + + + + + + + + + Description + + + + + + + {{block(ComponentStream)}} {{termplural(organize)}} the + {{block(Observation)}} entities associated with the + {{block(Component)}}. See {{package(Observation Information Model)}} + for the {{block(ComponentStream)}} model. > Note 1 to entry: In + the {{term(XML)}} representation, {{block(ComponentStream)}} + entities **MUST NOT** appear in the {{term(MTConnectDevices Response + Document)}}. > Note 2 to entry: In the {{term(XML)}} + representation, {{block(ComponentStream)}} entities **MUST** appear + only in the {{term(MTConnectStreams Response Document)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + The unque identifier for this device + + + + + + + + {{block(ComponentStream)}} {{termplural(organize)}} the + {{block(Observation)}} entities associated with the + {{block(Component)}}. See {{package(Observation Information Model)}} for + the {{block(ComponentStream)}} model. > Note 1 to entry: In the + {{term(XML)}} representation, {{block(ComponentStream)}} entities **MUST + NOT** appear in the {{term(MTConnectDevices Response Document)}}. > + Note 2 to entry: In the {{term(XML)}} representation, + {{block(ComponentStream)}} entities **MUST** appear only in the + {{term(MTConnectStreams Response Document)}}. + + + + + + + {{block(Samples)}} groups one or more {{block(Sample)}} entities. + See {{sect(Sample)}}. + + + + + + + {{block(Events)}} groups one or more {{block(Event)}} entities. See + {{sect(Event)}}. + + + + + + + Description + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + identifier of the maintenance activity. + + + + + + + The device manufacturer component name + + + + + + + Description + + + + + + + The unque identifier for this component + + + + + + + + {{block(Samples)}} groups one or more {{block(Sample)}} entities. See + {{sect(Sample)}}. + + + + + + + + + + {{block(Events)}} groups one or more {{block(Event)}} entities. See + {{sect(Event)}}. + + + + + + + + + + A collection of conditions + + + + + + + + + + The observation value for indeterminent data + + + + + + + Data is unavailable + + + + + + + + + + The events sequence number + + + + + + + The event subtype corresponding to the measurement subtype + + + + + + + The time the event occurred or recorded + + + + + + + identifier of the maintenance activity. + + + + + + + The unique identifier of the item being produced + + + + + + + The identifier of the sub-element this result is in reference to + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been deprecated in the MTConnect Standard. + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been extended and cannot be validated. + + + + + + + indicates if the Observation is verifiable and is in accordance with + the normative definitions within the MTConnect Standard. + + + + + + + + Integer event value + + + + + + + + Integer event value + + + + + + + + String event value + + + + + + + + DateTime String event value + + + + + + + + A list of axis names + + + + + + + + + + + + A list of axis for an event + + + + + + + + Common floating point event value + + + + + + + + Description + + + + + + + An optional indicator that the event or sample was reset + + + + + + + + Description + + + + + + + An unfaceted string event + + + + + + + + + + + + + + An unfaceted string event + + + + + + + An unfaceted string event + + + + + + + + + + + + + + An unfaceted string event + + + + + + + An unfaceted datetime event + + + + + + + + + + + + + + An unfaceted datetime event + + + + + + + An event with an integer value + + + + + + + + + + + + + + An event with an integer value + + + + + + + An event with an integer value + + + + + + + + + + + + + + An event with an integer value + + + + + + + An event with a three tuple floating point value + + + + + + + + + + + + + + An event with a three tuple floating point value + + + + + + + {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + + {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + Controlled vocabulary for ActuatorState + + + + + + + {{block(Actuator)}} is operating. + + + + + + + {{block(Actuator)}} is not operating. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + The type of asset + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + The type of asset + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + Controlled vocabulary for Availability + + + + + + + data source is active and capable of providing data. + + + + + + + data source is either inactive or not capable of providing data. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + + + + + + {{def(EventEnum::AVAILABILITY)}} + + + + + + + Controlled vocabulary for AxisCoupling + + + + + + + axes are physically connected to each other and operate as a single + unit. + + + + + + + axes are not physically connected to each other but are operating + together in lockstep. + + + + + + + axis is the master of the {{block(CoupledAxes)}}. + + + + + + + axis is a slave to the {{block(CoupledAxes)}}. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + + {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + Controlled vocabulary for AxisInterlock + + + + + + + axis lockout function is activated, power has been removed from the + axis, and the axis is allowed to move freely. + + + + + + + axis lockout function has not been activated, the axis may be + powered, and the axis is capable of being controlled by another + component. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + Controlled vocabulary for AxisState + + + + + + + axis is in its home position. + + + + + + + axis is in motion. + + + + + + + axis has been moved to a fixed position and is being maintained in + that position either electrically or mechanically. Action is + required to release the axis from this position. + + + + + + + axis is stopped. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_STATE)}} + + + + + + + {{def(EventEnum::BLOCK)}} + + + + + + + + + + {{def(EventEnum::BLOCK)}} + + + + + + + {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + + {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + Controlled vocabulary for ChuckInterlock + + + + + + + chuck cannot be unclamped. + + + + + + + chuck can be unclamped. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + Controlled vocabulary for ChuckState + + + + + + + {{block(Chuck)}} is open to the point of a positive confirmation. + + + + + + + {{block(Chuck)}} is closed to the point of a positive confirmation. + + + + + + + {{block(Chuck)}} is not closed to the point of a positive + confirmation and not open to the point of a positive confirmation. + It is in an intermediate position. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::CHUCK_STATE)}} + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + + {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + Controlled vocabulary for ControllerMode + + + + + + + {{block(Controller)}} is configured to automatically execute a + program. + + + + + + + {{block(Controller)}} is not executing an active program. It is + capable of receiving instructions from an external source – + typically an operator. The {{block(Controller)}} executes operations + based on the instructions received from the external source. + + + + + + + operator can enter a series of operations for the + {{block(Controller)}} to perform. The {{block(Controller)}} will + execute this specific series of operations and then stop. + + + + + + + {{block(Controller)}} is operating in a mode that restricts the + active program from processing its next process step without + operator intervention. + + + + + + + {{block(Controller)}} is currently functioning as a programming + device and is not capable of executing an active program. + + + + + + + axes of the device are commanded to stop, but the spindle continues + to function. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + Controlled vocabulary for ControllerModeOverride + + + + + + + {{block(ControllerModeOverride)}} is in the `ON` state and the mode + override is active. + + + + + + + {{block(ControllerModeOverride)}} is in the `OFF` state and the mode + override is inactive. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + + {{def(EventEnum::COUPLED_AXES)}} + + + + + + + {{def(EventEnum::DATE_CODE)}} + + + + + + + + + + {{def(EventEnum::DATE_CODE)}} + + + + + + + {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + + {{def(EventEnum::DEVICE_UUID)}} + + + + + + + Controlled vocabulary for Direction + + + + + + + clockwise rotation using the right-hand rule. + + + + + + + counter-clockwise rotation using the right-hand rule. + + + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::DIRECTION)}} + + + + + + + + + + + + + + {{def(EventEnum::DIRECTION)}} + + + + + + + Controlled vocabulary for DoorState + + + + + + + {{block(Door)}} is open to the point of a positive confirmation. + + + + + + + {{block(Door)}} is closed to the point of a positive confirmation. + + + + + + + {{block(Door)}} is not closed to the point of a positive + confirmation and not open to the point of a positive confirmation. + It is in an intermediate position. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::DOOR_STATE)}} + + + + + + + Controlled vocabulary for EmergencyStop + + + + + + + emergency stop circuit is complete and the piece of equipment, + component, or composition is allowed to operate. + + + + + + + operation of the piece of equipment, component, or composition is + inhibited. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + + + + + + {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + Controlled vocabulary for EndOfBar + + + + + + + {{block(EndOfBar)}} has been reached. + + + + + + + {{block(EndOfBar)}} has not been reached. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + + + + + + {{def(EventEnum::END_OF_BAR)}} + + + + + + + Controlled vocabulary for EquipmentMode + + + + + + + equipment is functioning in the mode designated by the `subType`. + + + + + + + equipment is not functioning in the mode designated by the + `subType`. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + Controlled vocabulary for Execution + + + + + + + {{block(Component)}} is ready to execute instructions. It is + currently idle. + + + + + + + {{block(Component)}} is actively executing an instruction. + + + + + + + {{block(Component)}} suspends the execution of the program due to an + external signal. Action is required to resume execution. + + + + + + + motion of the active axes are commanded to stop at their current + position. + + + + + + + {{block(Component)}} program is not `READY` to execute. + + + + + + + command from the program has intentionally interrupted execution. + The {{block(Component)}} **MAY** have another state that indicates + if the execution is interrupted or the execution ignores the + interrupt instruction. + + + + + + + command from the program has intentionally interrupted execution. + Action is required to resume execution. + + + + + + + program completed execution. + + + + + + + {{block(Component)}} suspends execution while a secondary operation + executes. Execution resumes automatically once the secondary + operation completes. + + + + + + + program has been intentionally optionally stopped using an M01 or + similar code. **DEPRECATED** in *version 1.4* and replaced with + `OPTIONAL_STOP`. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EXECUTION)}} + + + + + + + + + + + + + + {{def(EventEnum::EXECUTION)}} + + + + + + + Controlled vocabulary for FunctionalMode + + + + + + + {{block(Component)}} is currently producing product, ready to + produce product, or its current intended use is to be producing + product. + + + + + + + {{block(Component)}} is not currently producing product. It is being + prepared or modified to begin production of product. + + + + + + + {{block(Component)}} is not currently producing product. Typically, + it has completed the production of a product and is being modified + or returned to a neutral state such that it may then be prepared to + begin production of a different product. + + + + + + + {{block(Component)}} is not currently producing product. It is + currently being repaired, waiting to be repaired, or has not yet + been returned to a normal production status after maintenance has + been performed. + + + + + + + {{block(Component)}} is being used to prove-out a new process, + testing of equipment or processes, or any other active use that does + not result in the production of product. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + {{def(EventEnum::HARDNESS)}} + + + + + + + + + + {{def(EventEnum::HARDNESS)}} + + + + + + + {{def(EventEnum::LINE)}} + + + + + + + + + + {{def(EventEnum::LINE)}} + + + + + + + {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + + {{def(EventEnum::LINE_LABEL)}} + + + + + + + {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + + {{def(EventEnum::LINE_NUMBER)}} + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + + {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + {{def(EventEnum::MESSAGE)}} + + + + + + + + + + {{def(EventEnum::MESSAGE)}} + + + + + + + {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + + {{def(EventEnum::OPERATOR_ID)}} + + + + + + + {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + {{def(EventEnum::PALLET_ID)}} + + + + + + + {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + {{def(EventEnum::PART_COUNT)}} + + + + + + + Controlled vocabulary for PartDetect + + + + + + + part or work piece is detected or is present. + + + + + + + part or work piece is not detected or is not present. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_DETECT)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_DETECT)}} + + + + + + + {{def(EventEnum::PART_ID)}} + + + + + + + + + + {{def(EventEnum::PART_ID)}} + + + + + + + {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + + {{def(EventEnum::PART_NUMBER)}} + + + + + + + {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + + {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + Controlled vocabulary for PathMode + + + + + + + path is operating independently and without the influence of another + path. + + + + + + + path provides information or state values that influences the + operation of other {{block(DataItem)}} of similar type. + + + + + + + physical or logical parts which are not physically connected to each + other but are operating together. + + + + + + + axes associated with the path are mirroring the motion of the + `MASTER` path. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PATH_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::PATH_MODE)}} + + + + + + + Controlled vocabulary for PowerState + + + + + + + source of energy for an entity or the enabling signal providing + permission for the entity to perform its function(s) is present and + active. + + + + + + + source of energy for an entity or the enabling signal providing + permission for the entity to perform its function(s) is not present + or is disconnected. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::POWER_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::POWER_STATE)}} + + + + + + + Controlled vocabulary for PowerStatus + + + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::POWER_STATUS)}} + + + + + + + {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + + {{def(EventEnum::PROCESS_TIME)}} + + + + + + + {{def(EventEnum::PROGRAM)}} + + + + + + + + + + {{def(EventEnum::PROGRAM)}} + + + + + + + {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + Controlled vocabulary for ProgramEdit + + + + + + + {{block(Controller)}} is in the program edit mode. + + + + + + + {{block(Controller)}} is capable of entering the program edit mode + and no function is inhibiting a change to that mode. + + + + + + + {{block(Controller)}} is being inhibited by a function from entering + the program edit mode. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + Controlled vocabulary for ProgramLocationType + + + + + + + managed by the controller. + + + + + + + not managed by the controller. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is not + defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + + {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is not + defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + Controlled vocabulary for RotaryMode + + + + + + + axis is functioning as a spindle. + + + + + + + axis is configured to index. + + + + + + + position of the axis is being interpolated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::ROTARY_MODE)}} + + + + + + + {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command represents a + percentage change to the velocity calculated by a logic or motion + program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + + {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command represents a + percentage change to the velocity calculated by a logic or motion + program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + Controlled vocabulary for SpindleInterlock + + + + + + + power has been removed and the spindle cannot be operated. + + + + + + + spindle has not been deactivated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + + {{def(EventEnum::TOOL_GROUP)}} + + + + + + + {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + {{def(EventEnum::TOOL_ID)}} + + + + + + + {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + + {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + {{def(EventEnum::USER)}} + + + + + + + + + + {{def(EventEnum::USER)}} + + + + + + + {{def(EventEnum::VARIABLE)}} + + + + + + + + + + {{def(EventEnum::VARIABLE)}} + + + + + + + Controlled vocabulary for WaitState + + + + + + + execution is waiting while the equipment is powering up and is not + currently available to begin producing parts or products. + + + + + + + execution is waiting while the equipment is powering down but has + not fully reached a stopped state. + + + + + + + execution is waiting while one or more discrete workpieces are being + loaded. + + + + + + + execution is waiting while one or more discrete workpieces are being + unloaded. + + + + + + + execution is waiting while a tool or tooling is being loaded. + + + + + + + execution is waiting while a tool or tooling is being unloaded. + + + + + + + execution is waiting while material is being loaded. + + + + + + + execution is waiting while material is being unloaded. + + + + + + + execution is waiting while another process is completed before the + execution can resume. + + + + + + + execution is waiting while the equipment is pausing but the piece of + equipment has not yet reached a fully paused state. + + + + + + + execution is waiting while the equipment is resuming the production + cycle but has not yet resumed execution. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::WAIT_STATE)}} When {{property(Execution::result)}} is + not `WAIT`, {{property(Observation::isUnavailable)}} of + {{block(WaitState)}} **MUST** be `true`. + + + + + + + + + + + + + + {{def(EventEnum::WAIT_STATE)}} When {{property(Execution::result)}} is + not `WAIT`, {{property(Observation::isUnavailable)}} of + {{block(WaitState)}} **MUST** be `true`. + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + + {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + + {{def(EventEnum::WORK_OFFSET)}} + + + + + + + {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + + {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + {{def(EventEnum::FIRMWARE)}} + + + + + + + + + + {{def(EventEnum::FIRMWARE)}} + + + + + + + {{def(EventEnum::APPLICATION)}} + + + + + + + + + + {{def(EventEnum::APPLICATION)}} + + + + + + + {{def(EventEnum::LIBRARY)}} + + + + + + + + + + {{def(EventEnum::LIBRARY)}} + + + + + + + {{def(EventEnum::HARDWARE)}} + + + + + + + + + + {{def(EventEnum::HARDWARE)}} + + + + + + + {{def(EventEnum::NETWORK)}} + + + + + + + + + + {{def(EventEnum::NETWORK)}} + + + + + + + rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + + rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + + + + translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + Controlled vocabulary for PartStatus + + + + + + + part conforms to given requirements. + + + + + + + part does not conform to some given requirements. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_STATUS)}} If unique identifier is given, part + status is for that individual. If group identifier is given without a + unique identifier, then the status is assumed to be for the whole group. + + + + + + + + + + + + + + {{def(EventEnum::PART_STATUS)}} If unique identifier is given, part + status is for that individual. If group identifier is given without a + unique identifier, then the status is assumed to be for the whole group. + + + + + + + {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + + {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + {{def(EventEnum::PART_KIND_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_KIND_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + + {{def(EventEnum::ADAPTER_URI)}} + + + + + + + {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + + {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + Controlled vocabulary for ConnectionStatus + + + + + + + no connection at all. + + + + + + + {{term(agent)}} is waiting for a connection request from an + {{term(adapter)}}. + + + + + + + open connection. The normal state for the data transfer phase of the + connection. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + + {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + + {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + + {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + + {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + {{def(EventEnum::PART_GROUP_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_GROUP_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::PART_UNIQUE_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_UNIQUE_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + + {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + + {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + + {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + + {{def(EventEnum::LOAD_COUNT)}} + + + + + + + Controlled vocabulary for PartProcessingState + + + + + + + part occurrence is not actively being processed, but the processing + has not ended. Processing requirements exist that have not yet been + fulfilled. This is the default entry state when the part occurrence + is originally received. In some cases, the part occurrence may + return to this state while it waits for additional processing to be + performed. + + + + + + + part occurrence is actively being processed. + + + + + + + part occurrence is no longer being processed. A general state when + the reason for termination is unknown. + + + + + + + part occurrence has completed processing successfully. + + + + + + + process has been stopped during the processing. The part occurrence + will require special treatment. + + + + + + + processing of the part occurrence has come to a premature end. + + + + + + + terminal state when the part occurrence has been removed from the + equipment by an external entity and it no longer exists at the + equipment. + + + + + + + part occurrence has been skipped for processing on the piece of + equipment. + + + + + + + part occurrence has been processed completely. However, the + processing may have a problem. + + + + + + + part occurrence is waiting for transit. + + + + + + + part occurrence is being transported to its destination. + + + + + + + part occurrence has been placed at its designated destination. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + Controlled vocabulary for ProcessState + + + + + + + device is preparing to execute the process occurrence. + + + + + + + process occurrence is ready to be executed. + + + + + + + process occurrence is actively executing. + + + + + + + process occurrence is now finished. + + + + + + + process occurrence has been stopped and may be resumed. + + + + + + + process occurrence has come to a premature end and cannot be + resumed. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::PROCESS_STATE)}} + + + + + + + Controlled vocabulary for ValveState + + + + + + + {{block(ValveState)}} where flow is allowed and the aperture is + static. > Note: For a binary value, `OPEN` indicates the valve + has the maximum possible aperture. + + + + + + + valve is transitioning from a `CLOSED` state to an `OPEN` state. + + + + + + + {{block(ValveState)}} where flow is not possible, the aperture is + static, and the valve is completely shut. + + + + + + + valve is transitioning from an `OPEN` state to a `CLOSED` state. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::VALVE_STATE)}} + + + + + + + Controlled vocabulary for LockState + + + + + + + mechanism is engaged and preventing the associated + {{block(Component)}} from being opened or operated. + + + + + + + mechanism is disengaged and the associated {{block(Component)}} is + able to be opened or operated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::LOCK_STATE)}} + + + + + + + {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + + {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + + {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + Controlled vocabulary for OperatingMode + + + + + + + automatically execute instructions from a recipe or program. > + Note: Setpoint comes from a recipe. + + + + + + + execute instructions from an external agent or person. > Note 1 + to entry: Valve or switch is manipulated by an agent/person. > + Note 2 to entry: Direct control of the PID output. % of the range: A + user manually sets the % output, not the setpoint. + + + + + + + executes a single instruction from a recipe or program. > Note 1 + to entry: Setpoint is entered and fixed, but the PID is controlling. + > Note 2 to entry: Still goes through the PID control system. + > Note 3 to entry: Manual fixed entry from a recipe. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::OPERATING_MODE)}} + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + + {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + + {{def(EventEnum::FIXTURE_ID)}} + + + + + + + Controlled vocabulary for PartCountType + + + + + + + count is of individual items. + + + + + + + pre-specified group of items. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + + {{def(EventEnum::CLOCK_TIME)}} + + + + + + + {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + + {{def(EventEnum::NETWORK_PORT)}} + + + + + + + {{def(EventEnum::HOST_NAME)}} + + + + + + + + + + {{def(EventEnum::HOST_NAME)}} + + + + + + + Controlled vocabulary for LeakDetect + + + + + + + leak is currently being detected. + + + + + + + leak is currently not being detected. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + + + + + + {{def(EventEnum::LEAK_DETECT)}} + + + + + + + Controlled vocabulary for BatteryState + + + + + + + {{block(Component)}} is at it's maximum rated charge level. + + + + + + + {{block(Component)}}'s charge is increasing. + + + + + + + {{block(Component)}}'s charge is decreasing. + + + + + + + {{block(Component)}} is at it's minimum charge level. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::BATTERY_STATE)}} + + + + + + + {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + + {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + + {{def(EventEnum::SENSOR_STATE)}} + + + + + + + tabular {{def(EventEnum::COMPONENT_DATA)}} If the {{block(Component)}} + multiplicity can be determined, the device model **MUST** use a fixed + set of {{block(Component)}}s. {{block(ComponentData)}} **MUST** provide + a {{block(DataItem)}} {{block(Definition)}}. + + + + + + + + + + tabular {{def(EventEnum::COMPONENT_DATA)}} If the {{block(Component)}} + multiplicity can be determined, the device model **MUST** use a fixed + set of {{block(Component)}}s. {{block(ComponentData)}} **MUST** provide + a {{block(DataItem)}} {{block(Definition)}}. + + + + + + + tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + + tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + + tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + tabular representation of {{def(EventEnum::FEATURE_MEASUREMENT)}} + {{block(FeatureMeasurement)}} **MAY** include a {{term(characteristic)}} + in which case it **MAY** include a `CHARACTERISTIC_STATUS`. + + + + + + + + + + tabular representation of {{def(EventEnum::FEATURE_MEASUREMENT)}} + {{block(FeatureMeasurement)}} **MAY** include a {{term(characteristic)}} + in which case it **MAY** include a `CHARACTERISTIC_STATUS`. + + + + + + + {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, `RADIUS`, + `ANGLE`, `LENGTH`, etc. + + + + + + + + + + {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, `RADIUS`, + `ANGLE`, `LENGTH`, etc. + + + + + + + {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + + {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + + {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + Controlled vocabulary for CharacteristicStatus + + + + + + + measurement is within acceptable tolerances. + + + + + + + measurement is not within acceptable tolerances. + + + + + + + failed, but acceptable constraints achievable by utilizing + additional manufacturing processes. + + + + + + + measurement is indeterminate due to an equipment failure. + + + + + + + measurement cannot be determined. + + + + + + + measurement cannot be evaluated. + + + + + + + nominal provided without tolerance limits. {{cite(QIF 3:2018 + 5.10.2.6)}} + + + + + + + status of measurement cannot be determined. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + Controlled vocabulary for UncertaintyType + + + + + + + {{term(combined standard uncertainty)}}. + + + + + + + {{term(standard uncertainty)}} using arithmetic mean or average the + observations. {{cite(JCGM 100:2008 4.2)}} + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + + {{def(EventEnum::UNCERTAINTY)}} + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + + {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + + {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + + {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + + {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + {{def(EventEnum::THICKNESS)}} + + + + + + + + + + {{def(EventEnum::THICKNESS)}} + + + + + + + {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + + {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + + {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + + {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + + {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + + {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + + {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + Controlled vocabulary for InterfaceState + + + + + + + {{block(Interface)}} is currently operational and performing as + expected. + + + + + + + {{block(Interface)}} is currently not operational. + + + + + + + Value is indeterminate + + + + + + + + + {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + + + + + + {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + Discrete of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + Discrete of {{def(EventEnum::PART_COUNT)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_ID)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + Discrete of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::PALLET_ID)}} + + + + + + + Discrete of {{def(EventEnum::MESSAGE)}} + + + + + + + + + + Discrete of {{def(EventEnum::MESSAGE)}} + + + + + + + Discrete of {{def(EventEnum::BLOCK)}} + + + + + + + + + + Discrete of {{def(EventEnum::BLOCK)}} + + + + + + + The target rate a value can be sampled + + + + + + + + The number of items in the list + + + + + + + + Common floating point sample value + + + + + + + + Common floating point sample value + + + + + + + + Description + + + + + + + The rate the waveform was sampled at, default back to the value given + in the data item + + + + + + + An optional indicator that the event or sample was reset + + + + + + + The statistical operation on this data + + + + + + + The number of seconds since the reset of the statistic + + + + + + + + Description + + + + + + + A sample with a single floating point value + + + + + + + + + + + + + + A sample with a single floating point value + + + + + + + A sample with a three tuple floating point value + + + + + + + + + + + + + + A sample with a three tuple floating point value + + + + + + + The abstract waveform + + + + + + + + The number of samples + + + + + + + + + + The abstract waveform + + + + + + + Description + + + + + + + + + + + + + + Description + + + + + + + {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ACCELERATION)}} + + + + + + + {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + Time series of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + Time series of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE)}} + + + + + + + {{def(SampleEnum::ANGLE)}} + + + + + + + + + + {{def(SampleEnum::ANGLE)}} + + + + + + + Time series of {{def(SampleEnum::ANGLE)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGLE)}} + + + + + + + {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + Time series of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + Time series of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + Time series of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + Time series of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + Time series of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + {{def(SampleEnum::CONCENTRATION)}} + + + + + + + Time series of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + Time series of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + Time series of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + Time series of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + {{def(SampleEnum::DENSITY)}} + + + + + + + + + + {{def(SampleEnum::DENSITY)}} + + + + + + + Time series of {{def(SampleEnum::DENSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::DENSITY)}} + + + + + + + {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + Time series of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + Time series of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + Time series of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + {{def(SampleEnum::FLOW)}} + + + + + + + + + + {{def(SampleEnum::FLOW)}} + + + + + + + Time series of {{def(SampleEnum::FLOW)}} + + + + + + + + + + Time series of {{def(SampleEnum::FLOW)}} + + + + + + + {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + {{def(SampleEnum::FREQUENCY)}} + + + + + + + Time series of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + Time series of {{def(SampleEnum::FREQUENCY)}} + + + + + + + {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + Time series of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + Time series of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + {{def(SampleEnum::LENGTH)}} + + + + + + + + + + {{def(SampleEnum::LENGTH)}} + + + + + + + Time series of {{def(SampleEnum::LENGTH)}} + + + + + + + + + + Time series of {{def(SampleEnum::LENGTH)}} + + + + + + + {{def(SampleEnum::LEVEL)}} + + + + + + + + + + {{def(SampleEnum::LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::LEVEL)}} + + + + + + + {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + Time series of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + Time series of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + {{def(SampleEnum::LOAD)}} + + + + + + + + + + {{def(SampleEnum::LOAD)}} + + + + + + + Time series of {{def(SampleEnum::LOAD)}} + + + + + + + + + + Time series of {{def(SampleEnum::LOAD)}} + + + + + + + {{def(SampleEnum::MASS)}} + + + + + + + + + + {{def(SampleEnum::MASS)}} + + + + + + + Time series of {{def(SampleEnum::MASS)}} + + + + + + + + + + Time series of {{def(SampleEnum::MASS)}} + + + + + + + {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Example + + + + + + + + + + Example + + + + + + + {{def(SampleEnum::PH)}} + + + + + + + + + + {{def(SampleEnum::PH)}} + + + + + + + Time series of {{def(SampleEnum::PH)}} + + + + + + + + + + Time series of {{def(SampleEnum::PH)}} + + + + + + + {{def(SampleEnum::POSITION)}} + + + + + + + + + + {{def(SampleEnum::POSITION)}} + + + + + + + Time series of {{def(SampleEnum::POSITION)}} + + + + + + + + + + Time series of {{def(SampleEnum::POSITION)}} + + + + + + + {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Time series of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + Time series of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Description + + + + + + + + + + Description + + + + + + + Time series of {{def(SampleEnum::PRESSURE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PRESSURE)}} + + + + + + + {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + Time series of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + Time series of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + {{def(SampleEnum::RESISTANCE)}} + + + + + + + Time series of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + Time series of {{def(SampleEnum::RESISTANCE)}} + + + + + + + {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + Time series of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + Time series of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + {{def(SampleEnum::STRAIN)}} + + + + + + + + + + {{def(SampleEnum::STRAIN)}} + + + + + + + Time series of {{def(SampleEnum::STRAIN)}} + + + + + + + + + + Time series of {{def(SampleEnum::STRAIN)}} + + + + + + + {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + {{def(SampleEnum::TEMPERATURE)}} + + + + + + + Time series of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + Time series of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + {{def(SampleEnum::TENSION)}} + + + + + + + + + + {{def(SampleEnum::TENSION)}} + + + + + + + Time series of {{def(SampleEnum::TENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::TENSION)}} + + + + + + + {{def(SampleEnum::TILT)}} + + + + + + + + + + {{def(SampleEnum::TILT)}} + + + + + + + Time series of {{def(SampleEnum::TILT)}} + + + + + + + + + + Time series of {{def(SampleEnum::TILT)}} + + + + + + + {{def(SampleEnum::TORQUE)}} + + + + + + + + + + {{def(SampleEnum::TORQUE)}} + + + + + + + Time series of {{def(SampleEnum::TORQUE)}} + + + + + + + + + + Time series of {{def(SampleEnum::TORQUE)}} + + + + + + + {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::VELOCITY)}} + + + + + + + {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + {{def(SampleEnum::VISCOSITY)}} + + + + + + + Time series of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::VISCOSITY)}} + + + + + + + {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE)}} + + + + + + + {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + Time series of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + Time series of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + {{def(SampleEnum::WATTAGE)}} + + + + + + + Time series of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::WATTAGE)}} + + + + + + + {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::X_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + {{def(SampleEnum::DIAMETER)}} + + + + + + + Time series of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + Time series of {{def(SampleEnum::DIAMETER)}} + + + + + + + {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + + {{def(SampleEnum::ORIENTATION)}} + + + + + + + {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + Time series of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + {{def(SampleEnum::DECELERATION)}} + + + + + + + Time series of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::DECELERATION)}} + + + + + + + {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + The force per unit area measured relative to a vacuum. + + + + + + + + + + The force per unit area measured relative to a vacuum. + + + + + + + Time series of The force per unit area measured relative to a vacuum. + + + + + + + + + + Time series of The force per unit area measured relative to a vacuum. + + + + + + + {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + {{def(SampleEnum::OPENNESS)}} + + + + + + + Time series of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + Time series of {{def(SampleEnum::OPENNESS)}} + + + + + + + {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + {{def(SampleEnum::DEW_POINT)}} + + + + + + + Time series of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEW_POINT)}} + + + + + + + {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + + + + {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + Time series of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + Time series of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + + {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + The description of the Condition + + + + + + + + The device's severity + + + + + + + + Identifier of an individual condition activation provided by a piece of + equipment + + + + + + + + A qualifier for the condition + + + + + + + The value is too high + + + + + + + The value is too low + + + + + + + + + Description + + + + + + + + + type of the power source. + + + + + + + The component specific Notifcation code + + + + + + + The component specific Notifcation code + + + + + + + An optional attribute that helps qualify the condition + + + + + + + The statistical operation on this data + + + + + + + + + + Description + + + + + + + Condition that has transitioned from Normal to either Warning or Fault + + + + + + + + Identifier of an individual condition activation provided by a + piece of equipment + + + + + + + + + + Condition that has transitioned from Normal to either Warning or Fault + + + + + + + The conditon can not be determined. + + + + + + + + + + The conditon can not be determined. + + + + + + + {{term(condition state)}} that indicates operation within specified + limits. + + + + + + + + + + {{term(condition state)}} that indicates operation within specified + limits. + + + + + + + {{term(condition state)}} that requires concern and supervision and may + become hazardous if no action is taken. + + + + + + + + + + {{term(condition state)}} that requires concern and supervision and may + become hazardous if no action is taken. + + + + + + + {{term(condition state)}} that requires intervention to continue + operation to function properly. + + + + + + + + + + {{term(condition state)}} that requires intervention to continue + operation to function properly. + + + + + + + The tool location + + + + + + + + The number referenced in the program for this tool + + + + + + + + The number of times the cutter has been reconditioned + + + + + + + + The code for the connection to the machine + + + + + + + + The tool group associated with the tool + + + + + + + + A speed in RPM or mm/s + + + + + + + + + + A measurement value + + + + + + + + + + The number of location units required to hold this tool + + + + + + + + A measurement value + + + + + + + + The tool identifier + + + + + + + + The number of cutting edges + + + + + + + + The number of additional locations taken by a tool + + + + + + + + The life of the tool in time, wear, or parts + + + + + + + + An identifier for the insert + + + + + + + + A single or range of indexes. A range can be a comma separated set of + individual elements as in "1,2,3,4", or as a inclusive range + of values as in "1-10" or multiple ranges "1-4,6-10" + + + + + + + + + + A minimum value + + + + + + + + A maximum value + + + + + + + + A nominal value + + + + + + + + The material for a cutting item + + + + + + + + A maximum count value + + + + + + + + A application specific code + + + + + + + + A comman delimited list of manufactures + + + + + + + + A relationship + + + + + + + + The format of the definition + + + + + + + The definition will be provided in EXPRESS format + + + + + + + The definition will be provided in XML + + + + + + + The definition will be provided in uninterpreted TEXT + + + + + + + The definition will be provided in an unspecified format + + + + + + + + + The state of the tool. These can be combined to define the complete + cutting tool state + + + + + + + The tool is new + + + + + + + The cutting tool is available for use + + + + + + + The cutting tool is unavailable for use + + + + + + + The cutting tool is assigned to this proces + + + + + + + The cutting tool is NOT assigned to this device + + + + + + + The tool has been measured + + + + + + + An unregisterd state + + + + + + + The tool is being reconditioned + + + + + + + The tool is used + + + + + + + The tool is dead + + + + + + + The tool is currently out being reconditioned or sharpened + + + + + + + The tool is broken + + + + + + + The status of this cutter is undetermined + + + + + + + + + The direction of tool life count + + + + + + + The tool life counts up from the 0 to maximum + + + + + + + The tool life counts down from maximum to 0 + + + + + + + + + The direction of tool life count + + + + + + + The tool life measured in minutes + + + + + + + The tool life measured in parts made + + + + + + + Measurement of tool life in tool wear + + + + + + + + + The type of tool location + + + + + + + A location in a tool magazine. updated + + + + + + + A location in a turret, tool bar, or tool rack. updated + + + + + + + A location within a tool crib. updated + + + + + + + A location associated with a spindle + + + + + + + A location for a tool awaiting transfer from a tool magazine to + spindle or a turret + + + + + + + A location for a tool removed from a spindle or turret and awaiting + return to a tool magazine + + + + + + + A location for a tool awaiting transfer to a tool magazine or turret + from outside of the piece of equipment. + + + + + + + A location for a tool removed from a tool magazine or turret + awaiting transfer to a location outside of the piece of equipment. + + + + + + + A location for a tool that is no longer useable and is awaiting + removal from a tool magazine or turret. + + + + + + + A location associated with an end effector + + + + + + + + + detailed structure of the cutting tool which is static during its + lifecycle. {{cite(ISO 13399)}}. + + + + + + + Any elements + + + + + + + + identifies the expected representation of the enclosed data. + + + + + + + + {{block(Asset)}} that physically removes the material from the workpiece + by shear deformation. + + + + + + + + + See {{sect(Description)}}. + + + + + + + + + detailed structure of the cutting tool which is static + during its lifecycle. {{cite(ISO 13399)}}. + + + + + + + data regarding the application or use of the tool. This data + is provided by various pieces of equipment (i.e. machine + tool, presetter) and statistical process control + applications. Life cycle data will not remain static, but + will change periodically when a tool is used or measured. + + + + + + + + data regarding the application or use of the tool. This data + is provided by various pieces of equipment (i.e. machine tool, + presetter) and statistical process control applications. Life + cycle data will not remain static, but will change + periodically when a tool is used or measured. + + + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + The manufacturer of this asset + + + + + + + {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + {{block(Asset)}} that physically removes the material from the workpiece + by shear deformation. + + + + + + + {{block(Asset)}} that describes the static cutting tool geometries and + nominal values as one would expect from a tool catalog. + + + + + + + + + See {{sect(Description)}}. + + + + + + + + + detailed structure of the cutting tool which is static + during its lifecycle. {{cite(ISO 13399)}}. + + + + + + + data regarding the application or use of the tool. This data + is provided by various pieces of equipment (i.e. machine + tool, presetter) and statistical process control + applications. Life cycle data will not remain static, but + will change periodically when a tool is used or measured. + + + + + + + + data regarding the application or use of the tool. This data + is provided by various pieces of equipment (i.e. machine tool, + presetter) and statistical process control applications. Life + cycle data will not remain static, but will change + periodically when a tool is used or measured. + + + + + + + + + identifier for a class of cutting tools. + + + + + + + + + + {{block(Asset)}} that describes the static cutting tool geometries and + nominal values as one would expect from a tool catalog. + + + + + + + A archetypical cutting tool life cycle definition + + + + + + + number of times the cutter has been reconditioned. + + + + + + + The life of the cutting tool assembly + + + + + + + tool group this tool is assigned in the part program. + + + + + + + number of the tool as referenced in the part program. + + + + + + + constrained process spindle speed for the tool in + revolutions/minute. The {{property(ProcessSpindleSpeed::value)}} + **MAY** contain the nominal process target spindle speed if + available. If {{block(ProcessSpindleSpeed)}} is provided, at least + one value of {{property(ProcessSpindleSpeed::maximum)}}, + {{property(ProcessSpindleSpeed::nominal)}}, or + {{property(ProcessSpindleSpeed::minimum)}} **MUST** be specified. + + + + + + + constrained process feed rate for the tool in mm/s. The + {{property(ProcessFeedRate::value)}} **MAY** contain the nominal + process target feed rate if available. If {{block(ProcessFeedRate)}} + is provided, at least one value of + {{property(ProcessFeedRate::maximum)}}, + {{property(ProcessFeedRate::nominal)}}, or + {{property(ProcessFeedRate::minimum)}} **MUST** be specified. + + + + + + + identifier for the capability to connect any component of the + cutting tool together, except Assembly Items, on the machine side. + Code: `CCMS` + + + + + + + {{block(Measurements)}} groups one or more {{block(Measurement)}} + subtypes. See {{sect(Measurement)}}. + + + + + + + {{block(CuttingItems)}} groups one or more {{block(CuttingItem)}} + entities. See {{sect(CuttingItem)}} and {{package(Cutting Item)}} + for more detail. + + + + + + + + + data regarding the application or use of the tool. This data is provided + by various pieces of equipment (i.e. machine tool, presetter) and + statistical process control applications. Life cycle data will not + remain static, but will change periodically when a tool is used or + measured. + + + + + + + {{block(CutterStatus)}} provides the status of the assembly and + {{term(organize)}} one or more {{block(Status)}} entities. See + {{sect(Status)}}. The following combinations of {{block(Status)}} + entities **MUST NOT** occur for a {{block(CutterStatus)}}: * `NEW` + **MUST NOT** be used with `USED`, `RECONDITIONED`, or `EXPIRED`. * + `UNKNOWN` **MUST NOT** be used with any other status. * `ALLOCATED` + and `UNALLOCATED` **MUST NOT** be used together. * `AVAILABLE` and + `UNAVAILABLE` **MUST NOT** be used together. * If the tool is + `EXPIRED`, `BROKEN`, or `NOT_REGISTERED` it **MUST NOT** be + `AVAILABLE`. + + + + + + + number of times the cutter has been reconditioned. + + + + + + + Description + + + + + + + tool group this tool is assigned in the part program. + + + + + + + number of the tool as referenced in the part program. + + + + + + + Description + + + + + + + constrained process spindle speed for the tool in + revolutions/minute. The {{property(ProcessSpindleSpeed::value)}} + **MAY** contain the nominal process target spindle speed if + available. If {{block(ProcessSpindleSpeed)}} is provided, at least + one value of {{property(ProcessSpindleSpeed::maximum)}}, + {{property(ProcessSpindleSpeed::nominal)}}, or + {{property(ProcessSpindleSpeed::minimum)}} **MUST** be specified. + + + + + + + constrained process feed rate for the tool in mm/s. The + {{property(ProcessFeedRate::value)}} **MAY** contain the nominal + process target feed rate if available. If {{block(ProcessFeedRate)}} + is provided, at least one value of + {{property(ProcessFeedRate::maximum)}}, + {{property(ProcessFeedRate::nominal)}}, or + {{property(ProcessFeedRate::minimum)}} **MUST** be specified. + + + + + + + identifier for the capability to connect any component of the + cutting tool together, except Assembly Items, on the machine side. + Code: `CCMS` + + + + + + + {{block(Measurements)}} groups one or more {{block(Measurement)}} + subtypes. See {{sect(Measurement)}}. + + + + + + + {{block(CuttingItems)}} groups one or more {{block(CuttingItem)}} + entities. See {{sect(CuttingItem)}} and {{package(Cutting Item)}} + for more detail. + + + + + + + + + reference information about the {{property(Asset::assetId)}} and/or the + URL of the data source of {{block(CuttingToolArchetype)}}. + + + + + + + + identifies the {{block(Component)}}, {{block(DataItem)}}, or + {{block(Composition)}} from which a measured value originates. + + + + + + + + + + {{block(CutterStatus)}} provides the status of the assembly and + {{term(organize)}} one or more {{block(Status)}} entities. See + {{sect(Status)}}. The following combinations of {{block(Status)}} + entities **MUST NOT** occur for a {{block(CutterStatus)}}: * `NEW` + **MUST NOT** be used with `USED`, `RECONDITIONED`, or `EXPIRED`. * + `UNKNOWN` **MUST NOT** be used with any other status. * `ALLOCATED` and + `UNALLOCATED` **MUST NOT** be used together. * `AVAILABLE` and + `UNAVAILABLE` **MUST NOT** be used together. * If the tool is `EXPIRED`, + `BROKEN`, or `NOT_REGISTERED` it **MUST NOT** be `AVAILABLE`. + + + + + + + status of the cutting tool. + + + + + + + + + Description + + + + + + + + The type of location + + + + + + + number of locations at lower index values from this location. + + + + + + + number of locations at higher index value from this location. + + + + + + + Description + + + + + + + Description + + + + + + + Description + + + + + + + The tool bar associated with a tool + + + + + + + Description + + + + + + + + + + number of times the cutter has been reconditioned. + + + + + + + + The maximum number of times this tool can be reconditioned + + + + + + + + + + constrained process spindle speed for the tool in revolutions/minute. + The {{property(ProcessSpindleSpeed::value)}} **MAY** contain the nominal + process target spindle speed if available. If + {{block(ProcessSpindleSpeed)}} is provided, at least one value of + {{property(ProcessSpindleSpeed::maximum)}}, + {{property(ProcessSpindleSpeed::nominal)}}, or + {{property(ProcessSpindleSpeed::minimum)}} **MUST** be specified. + + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + + + + constrained process feed rate for the tool in mm/s. The + {{property(ProcessFeedRate::value)}} **MAY** contain the nominal process + target feed rate if available. If {{block(ProcessFeedRate)}} is + provided, at least one value of {{property(ProcessFeedRate::maximum)}}, + {{property(ProcessFeedRate::nominal)}}, or + {{property(ProcessFeedRate::minimum)}} **MUST** be specified. + + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + + + + Description + + + + + + + + The number of significant digits + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + The native units for the measurement, if different from units + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + + + + Description + + + + + + + Measurements for both the assembly and the cutting item + + + + + + + + + + Measurements for both the assembly and the cutting item + + + + + + + Measurements for the assembly + + + + + + + + + + Measurements for the assembly + + + + + + + Measurements for the cutting item + + + + + + + + + + Measurements for the cutting item + + + + + + + A collection of assembly measurements + + + + + + + + + + + dimension from the yz-plane to the furthest point of the tool item or + adaptive item measured in the -X direction. + + + + + + + + + + dimension from the yz-plane to the furthest point of the tool item or + adaptive item measured in the -X direction. + + + + + + + total weight of the cutting tool in grams. The force exerted by the mass + of the cutting tool. + + + + + + + + + + total weight of the cutting tool in grams. The force exerted by the mass + of the cutting tool. + + + + + + + distance from the gauge plane or from the end of the shank to the + furthest point on the tool, if a gauge plane does not exist, to the + cutting reference point determined by the main function of the tool. The + {{block(CuttingTool)}} functional length will be the length of the + entire tool, not a single cutting item. Each {{block(CuttingItem)}} can + have an independent {{block(FunctionalLength)}} represented in its + measurements. + + + + + + + + + + distance from the gauge plane or from the end of the shank to the + furthest point on the tool, if a gauge plane does not exist, to the + cutting reference point determined by the main function of the tool. The + {{block(CuttingTool)}} functional length will be the length of the + entire tool, not a single cutting item. Each {{block(CuttingItem)}} can + have an independent {{block(FunctionalLength)}} represented in its + measurements. + + + + + + + largest diameter of the body of a tool item. + + + + + + + + + + largest diameter of the body of a tool item. + + + + + + + distance measured along the X axis from that point of the item closest + to the workpiece, including the cutting item for a tool item but + excluding a protruding locking mechanism for an adaptive item, to either + the front of the flange on a flanged body or the beginning of the + connection interface feature on the machine side for cylindrical or + prismatic shanks. + + + + + + + + + + distance measured along the X axis from that point of the item closest + to the workpiece, including the cutting item for a tool item but + excluding a protruding locking mechanism for an adaptive item, to either + the front of the flange on a flanged body or the beginning of the + connection interface feature on the machine side for cylindrical or + prismatic shanks. + + + + + + + maximum diameter of a circle on which the defined point Pk of each of + the master inserts is located on a tool item. The normal of the machined + peripheral surface points towards the axis of the cutting tool. + + + + + + + + + + maximum diameter of a circle on which the defined point Pk of each of + the master inserts is located on a tool item. The normal of the machined + peripheral surface points towards the axis of the cutting tool. + + + + + + + dimension between two parallel tangents on the outside edge of a flange. + + + + + + + + + + dimension between two parallel tangents on the outside edge of a flange. + + + + + + + maximum engagement of the cutting edge or edges with the workpiece + measured perpendicular to the feed motion. + + + + + + + + + + maximum engagement of the cutting edge or edges with the workpiece + measured perpendicular to the feed motion. + + + + + + + largest length dimension of the cutting tool including the master insert + where applicable. + + + + + + + + + + largest length dimension of the cutting tool including the master insert + where applicable. + + + + + + + dimension of the diameter of a cylindrical portion of a tool item or an + adaptive item that can participate in a connection. + + + + + + + + + + dimension of the diameter of a cylindrical portion of a tool item or an + adaptive item that can participate in a connection. + + + + + + + dimension of the height of the shank. + + + + + + + + + + dimension of the height of the shank. + + + + + + + dimension of the length of the shank. + + + + + + + + + + dimension of the length of the shank. + + + + + + + maximum length of a cutting tool that can be used in a particular + cutting operation including the non-cutting portions of the tool. + + + + + + + + + + maximum length of a cutting tool that can be used in a particular + cutting operation including the non-cutting portions of the tool. + + + + + + + Abstract cutter life + + + + + + + + One of time, part count, or wear + + + + + + + The count up or count down + + + + + + + {{term(condition state)}} that requires concern and supervision + and may become hazardous if no action is taken. + + + + + + + Maximum tool life + + + + + + + The life when the tool is new + + + + + + + + + + A collection of assembly measurements + + + + + + + + + + + diameter of a circle on which the defined point Pk located on this + cutting tool. The normal of the machined peripheral surface points + towards the axis of the cutting tool. + + + + + + + + + + diameter of a circle on which the defined point Pk located on this + cutting tool. The normal of the machined peripheral surface points + towards the axis of the cutting tool. + + + + + + + nominal radius of a rounded corner measured in the X Y-plane. + + + + + + + + + + nominal radius of a rounded corner measured in the X Y-plane. + + + + + + + theoretical length of the cutting edge of a cutting item over sharp + corners. + + + + + + + + + + theoretical length of the cutting edge of a cutting item over sharp + corners. + + + + + + + distance from the basal plane of the tool item to the cutting point. + + + + + + + + + + distance from the basal plane of the tool item to the cutting point. + + + + + + + theoretical sharp point of the cutting tool from which the major + functional dimensions are taken. + + + + + + + + + + theoretical sharp point of the cutting tool from which the major + functional dimensions are taken. + + + + + + + dimension between two parallel tangents on the outside edge of a flange. + + + + + + + + + + dimension between two parallel tangents on the outside edge of a flange. + + + + + + + distance between the cutting reference point and the rear backing + surface of a turning tool or the axis of a boring bar. + + + + + + + + + + distance between the cutting reference point and the rear backing + surface of a turning tool or the axis of a boring bar. + + + + + + + angle between the tool rake plane and a plane parallel to the xy-plane + measured in the tool cutting edge plane + + + + + + + + + + angle between the tool rake plane and a plane parallel to the xy-plane + measured in the tool cutting edge plane + + + + + + + diameter of a circle to which all edges of a equilateral and round + regular insert are tangential. + + + + + + + + + + diameter of a circle to which all edges of a equilateral and round + regular insert are tangential. + + + + + + + angle between the major cutting edge and the same cutting edge rotated + by 180 degrees about the tool axis. + + + + + + + + + + angle between the major cutting edge and the same cutting edge rotated + by 180 degrees about the tool axis. + + + + + + + length of a portion of a stepped tool that is related to a corresponding + cutting diameter measured from the cutting reference point of that + cutting diameter to the point on the next cutting edge at which the + diameter starts to change. + + + + + + + + + + length of a portion of a stepped tool that is related to a corresponding + cutting diameter measured from the cutting reference point of that + cutting diameter to the point on the next cutting edge at which the + diameter starts to change. + + + + + + + angle between a major edge on a step of a stepped tool and the same + cutting edge rotated 180 degrees about its tool axis. + + + + + + + + + + angle between a major edge on a step of a stepped tool and the same + cutting edge rotated 180 degrees about its tool axis. + + + + + + + angle between the tool cutting edge plane and the tool feed plane + measured in a plane parallel the xy-plane. + + + + + + + + + + angle between the tool cutting edge plane and the tool feed plane + measured in a plane parallel the xy-plane. + + + + + + + angle between the tool cutting edge plane and a plane perpendicular to + the tool feed plane measured in a plane parallel the xy-plane. + + + + + + + + + + angle between the tool cutting edge plane and a plane perpendicular to + the tool feed plane measured in a plane parallel the xy-plane. + + + + + + + measure of the length of a wiper edge of a cutting item. + + + + + + + + + + measure of the length of a wiper edge of a cutting item. + + + + + + + angle of the tool with respect to the workpiece for a given process. The + value is application specific. + + + + + + + + + + angle between the driving mechanism locator on a tool item and the main + cutting edge. + + + + + + + + + + The location of the cutting item - not yet restricted. + + + + + + + + {{block(CuttingItems)}} groups one or more {{block(CuttingItem)}} + entities. See {{sect(CuttingItem)}} and {{package(Cutting Item)}} for + more detail. + + + + + + + part of of the tool that physically removes the material from the + workpiece by shear deformation. + + + + + + + + The number of edges + + + + + + + + part of of the tool that physically removes the material from the + workpiece by shear deformation. + + + + + + + See {{sect(Description)}}. + + + + + + + {{block(CutterStatus)}} provides the status of the assembly and + {{term(organize)}} one or more {{block(Status)}} entities. See + {{sect(Status)}}. The following combinations of {{block(Status)}} + entities **MUST NOT** occur for a {{block(CutterStatus)}}: * `NEW` + **MUST NOT** be used with `USED`, `RECONDITIONED`, or `EXPIRED`. * + `UNKNOWN` **MUST NOT** be used with any other status. * `ALLOCATED` + and `UNALLOCATED` **MUST NOT** be used together. * `AVAILABLE` and + `UNAVAILABLE` **MUST NOT** be used together. * If the tool is + `EXPIRED`, `BROKEN`, or `NOT_REGISTERED` it **MUST NOT** be + `AVAILABLE`. + + + + + + + free form description of the location on the cutting tool. For + clarity, the words `FLUTE`, `INSERT`, and `CARTRIDGE` **SHOULD** be + used to assist in noting the location of a {{block(CuttingItem)}}. + {{property(CuttingItem::Locus)}} **MAY** be any free form string, + but **SHOULD** adhere to the following rules: * The location + numbering **SHOULD** start at the furthest {{block(CuttingItem)}} + and work it’s way back to the {{block(CuttingItem)}} closest to the + gauge line. * Flutes **SHOULD** be identified as such using the word + `FLUTE`:. For example: `FLUTE`: 1, `INSERT`: 2 - would indicate the + first flute and the second furthest insert from the end of the tool + on that flute. * Other designations such as `CARTRIDGE` **MAY** be + included, but should be identified using upper case and followed by + a colon (:). + + + + + + + life of a {{block(CuttingItem)}}. + + + + + + + tool group this tool is assigned in the part program. + + + + + + + {{block(Measurements)}} groups one or more {{block(Measurement)}} + subtypes. See {{sect(Measurement)}}. + + + + + + + + The unique identifier of this insert in this assembly + + + + + + + The manufacturer identifier of this cutting item + + + + + + + The material used for the cutting item + + + + + + + The manufacturer of this asset + + + + + + + + The version of the file + + + + + + + + The mime type of the file + + + + + + + + The size in bytes of the file + + + + + + + + The name of the file + + + + + + + + Extended tyoe for The category of application that will use this file + + + + + + + + + + The category of application that will use this file + + + + + + + Files regarding the fully assembled product + + + + + + + Device related files + + + + + + + Files relating to the handling of material + + + + + + + File relating to equipment maintenance + + + + + + + Files relating to a part + + + + + + + Files related to the manufacturing process + + + + + + + Files related to the quality inspection + + + + + + + Files related to the setup of a process + + + + + + + + + The category of application that will use this file + + + + + + + + Extended tyoe for The type classification of a file + + + + + + + + + + The type classification of a file + + + + + + + Computer aided design files or drawings + + + + + + + Generic data + + + + + + + Documentation regarding a category of file + + + + + + + User instructions regarding the execution of a task + + + + + + + The data related to the history of a machine or process + + + + + + + Machine instructions to perform a process + + + + + + + + + The type classification of a file + + + + + + + + {{block(AbstractFile)}} type that provides information common to all + versions of a file. + + + + + + + + + {{block(FileProperties)}} groups one or more + {{block(FileProperty)}} entities for a {{block(File)}}. See + {{sect(FileProperty)}}. + + + + + + + {{block(FileComments)}} groups one or more + {{block(FileComment)}} entities for a {{block(File)}}. See + {{sect(FileComment)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + The mime type of the file + + + + + + + The classification of this file + + + + + + + The sub classification of this file + + + + + + + + + + {{block(AbstractFile)}} type that provides information common to all + versions of a file. + + + + + + + {{block(FileProperties)}} groups one or more {{block(FileProperty)}} + entities for a {{block(File)}}. See {{sect(FileProperty)}}. + + + + + + + key-value pair providing additional metadata about a + {{block(File)}}. + + + + + + + + + The value of a file property + + + + + + + + key-value pair providing additional metadata about a {{block(File)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + + + + File state + + + + + + + used for processes other than production or otherwise defined. + + + + + + + used for production processes + + + + + + + the content is modified from PRODUCTION or EXPERIMENTAL (Note: To + capture northbound changes. execution -> prod engineering) + + + + + + + + + An X501 Public Key + + + + + + + + A secure hash + + + + + + + + A file time + + + + + + + + {{block(AbstractFile)}} type that provides information about the + {{block(File)}} instance and its {{term(URL)}}. + + + + + + + + + {{block(FileProperties)}} groups one or more + {{block(FileProperty)}} entities for a {{block(File)}}. See + {{sect(FileProperty)}}. + + + + + + + {{block(FileComments)}} groups one or more + {{block(FileComment)}} entities for a {{block(File)}}. See + {{sect(FileComment)}}. + + + + + + + {{term(URL)}} reference to the file location. + + + + + + + secure hash of the file. + + + + + + + public key used to verify the signature. + + + + + + + {{block(Destinations)}} groups one or more + {{block(Destination)}} entities. See {{sect(Destination)}}. + + + + + + + time the file was created. + + + + + + + time the file was modified. + + + + + + + + identifier of the maintenance activity. + + + + + + + The mime type of the file + + + + + + + The classification of this file + + + + + + + The sub classification of this file + + + + + + + The size in bytes + + + + + + + The version identifier + + + + + + + The file state + + + + + + + + + + {{block(AbstractFile)}} type that provides information about the + {{block(File)}} instance and its {{term(URL)}}. + + + + + + + {{term(URL)}} reference to the file location. + + + + + + + + {{term(URL)}} giving the location of the image file. + + + + + + + Description + + + + + + + + + + Organizes file destinations + + + + + + + reference to the target {{block(Device)}} for this {{block(File)}}. + + + + + + + + + The Destination is a reference to the target Device for this File + + + + + + + + + + {{block(FileComments)}} groups one or more {{block(FileComment)}} + entities for a {{block(File)}}. See {{sect(FileComment)}}. + + + + + + + remark or interpretation for human interpretation associated with a + {{block(File)}} or {{block(FileArchetype)}}. + + + + + + + + + the text of the comment + + + + + + + + remark or interpretation for human interpretation associated with a + {{block(File)}} or {{block(FileArchetype)}}. + + + + + + + + The time the comment was made + + + + + + + + + + Extended tyoe for contained QIF Document type as defined in the QIF + Standard. + + + + + + + + + + contained QIF Document type as defined in the QIF Standard. + + + + + + + + + + + + + + + contained QIF Document type as defined in the QIF Standard. + + + + + + + + {{block(Asset)}} that carries the QIF Document. + + + + + + + + + + + + + + + The unique identifier for the material + + + + + + + + + + {{block(Asset)}} that carries the QIF Document. + + + + + + + + + + + + any element + + + + + + + + + The type of the material container. + + + + + + + + The serial number of the material container + + + + + + + + The ISO process type supported by this {{term(raw material)}} + + + + + + + + The type of material. + + + + + + + + The name of the raw feed stock manufacturer. + + + + + + + + The manufacturing date of the raw feed stock from the feed stock + manufacturer. + + + + + + + + The lot code of the raw feed stock from the feed stock manufacturer. + + + + + + + + The ASTM standard code that the material complies with. + + + + + + + + The lot code of the material contained within the material container. + + + + + + + + The form of the material in the material container. + + + + + + + + The date when the material container was first used. + + + + + + + + The date when the material container was last used. + + + + + + + + The amount of material initially placed in the material container when + manufactured. + + + + + + + + The dimension of material initially placed in the material container + when manufactured. + + + + + + + + The quantity of material initially placed in the material container when + manufactured. + + + + + + + + The quantity of material currently contained in the material container + + + + + + + + The dimension of material currently contained in the material container + + + + + + + + The quantity of material currently contained in the material container + + + + + + + + Extended tyoe for form of the {{term(raw material)}}. + + + + + + + + + + form of the {{term(raw material)}}. + + + + + + + + + + + + + + + + + + form of the {{term(raw material)}}. + + + + + + + + material used as the {{block(RawMaterial)}} + + + + + + + manufacturer's lot code of the material. + + + + + + + name of the material manufacturer. + + + + + + + manufacturing date of the material from the material manufacturer. + + + + + + + lot code of the raw feed stock for the material, from the feed stock + manufacturer. + + + + + + + {{term(ASTM)}} standard code that the material complies with. + + + + + + + + The unique identifier for the material + + + + + + + identifier of the maintenance activity. + + + + + + + The type of material. + + + + + + + + {{block(Asset)}} that represents {{term(raw material)}}. + + + + + + + + + form of the {{term(raw material)}}. + + + + + + + {{block(Material)}} has existing usable volume. + + + + + + + manufacturing date of the material from the material + manufacturer. + + + + + + + date {{term(raw material)}} was first used. + + + + + + + date {{term(raw material)}} was last used. + + + + + + + amount of material initially placed in {{term(raw material)}} + when manufactured. + + + + + + + dimension of material initially placed in {{term(raw material)}} + when manufactured. + + + + + + + quantity of material initially placed in {{term(raw material)}} + when manufactured. + + + + + + + amount of material currently in {{term(raw material)}}. + + + + + + + dimension of material currently in {{term(raw material)}}. + + + + + + + quantity of material currently in {{term(raw material)}}. + + + + + + + {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, + materials, or other types of goods. + + + + + + + + identifier of the maintenance activity. + + + + + + + The type of container holding the {{term(raw material)}}. + + + + + + + The ISO process type supported by this {{term(raw material)}}. + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + + {{block(Asset)}} that represents {{term(raw material)}}. + + + + + + + property that determines the characteristic or behavior of an entity. + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + single data value that is expected to be reported for a + {{block(DataItem)}}. {{property(Constraints::Value)}} **MUST NOT** + be used in conjunction with any other {{block(Constraint)}} + elements. + + + + + + + + The identifier of the parameter + + + + + + + identifier of the maintenance activity. + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + + {{block(Parameters)}} groups one or more {{block(Parameter)}} entities. + See {{sect(Parameter)}}. + + + + + + + property that determines the characteristic or behavior of an + entity. + + + + + + + + + set of {{block(Parameter)}}s. + + + + + + + {{block(Parameters)}} groups one or more {{block(Parameter)}} + entities. See {{sect(Parameter)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + + {{block(ParameterSets)}} groups one or more {{block(ParameterSet)}} + entities. See {{sect(ParameterSet)}}. + + + + + + + set of {{block(Parameter)}}s. + + + + + + + + + set of {{block(ParameterSet)}}s that govern the functionality of the + related {{block(Component)}}. + + + + + + + + + {{block(ParameterSets)}} groups one or more + {{block(ParameterSet)}} entities. See {{sect(ParameterSet)}}. + + + + + + + + + + + set of {{block(ParameterSet)}}s that govern the functionality of the + related {{block(Component)}}. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The number of significant digits + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + The native units for the measurement, if different from units + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{block(Measurements)}} groups one or more + {{block(Measurement)}} subtypes. See {{sect(Measurement)}}. + + + + + + + + + + + + + + {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{block(Measurements)}} groups one or more + {{block(Measurement)}} subtypes. See {{sect(Measurement)}}. + + + + + + + + {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/schemas/MTConnectDevices_2.5.xsd b/schemas/MTConnectDevices_2.5.xsd new file mode 100644 index 000000000..9181ea791 --- /dev/null +++ b/schemas/MTConnectDevices_2.5.xsd @@ -0,0 +1,10437 @@ + + + + + + + + root entity of an {{term(MTConnectDevices Response Document)}} that + contains the {{term(Device Information Model)}} of one or more + {{block(Device)}} entities. + ![MTConnectDevices](figures/MTConnectDevices.png + "MTConnectDevices"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectDevices)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + The sender of the message + + + + + + + + The date and time the document was created + + + + + + + + A sequence number + + + + + + + + + + + A debugging flag for testing. + + + + + + + + The instance number of the agent, used for fault tolerance + + + + + + + + + + + The size of the agents buffer + + + + + + + + + + + The time the sample was reported + + + + + + + + The time a sample occurred + + + + + + + + A version number + + + + + + + + A short name for any element + + + + + + + + A universally unique id that uniquely identifies the element for + it's entire life + + + + + + + + A serial number for a piece of equipment + + + + + + + + The measurement source + + + + + + + + A sample rate in milliseconds per sample + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + + An identifier + + + + + + + + The number significant digits + + + + + + + + The item's reference to the Device model composition + + + + + + + + A length of time in seconds + + + + + + + + A flag indicating the item has been removed + + + + + + + + The key for adata set + + + + + + + + A timestamp in 8601 format of the last update of the Device information + for any device + + + + + + + + The unique id of the asset + + + + + + + + An asset type + + + + + + + + The maximum number of assets + + + + + + + + + + + The number of assets + + + + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + The limit of a value + + + + + + + + Common floating point sample value + + + + + + + + + + + + A three dimensional value 'X Y Z' or 'A B C' + + + + + + + + + + + A description + + + + + + + + Extended tyoe for The types of measurements available + + + + + + + + + + The types of measurements available + + + + + + + positive rate of change of velocity. + + + + + + + accumulated time for an activity or event. + + + + + + + strength of electrical current. **DEPRECATED** in *Version 1.6*. + Replaced by `AMPERAGE_AC` and `AMPERAGE_DC`. + + + + + + + angular position. + + + + + + + positive rate of change of angular velocity. + + + + + + + rate of change of angular position. + + + + + + + feedrate of a linear axis. + + + + + + + fluid capacity of an object or container. + + + + + + + geometric capacity of an object or container. + + + + + + + percentage of one component within a mixture of components. + + + + + + + ability of a material to conduct electricity. + + + + + + + speed difference (relative velocity) between the cutting mechanism + and the surface of the workpiece it is operating on. + + + + + + + volumetric mass of a material per unit volume of that material. + + + + + + + rate of change in spatial volume of material deposited in an + additive manufacturing process. + + + + + + + density of the material deposited in an additive manufacturing + process per unit of volume. + + + + + + + mass of the material deposited in an additive manufacturing process. + + + + + + + rate at which a spatial volume of material is deposited in an + additive manufacturing process. + + + + + + + spatial volume of material to be deposited in an additive + manufacturing process. + + + + + + + change in position of an object. + + + + + + + {{block(Wattage)}} used or generated by a component over an interval + of time. + + + + + + + amount of time a piece of equipment or a sub-part of a piece of + equipment has performed specific activities. + + + + + + + amount of a substance remaining compared to the planned maximum + amount of that substance. + + + + + + + rate of flow of a fluid. + + + + + + + number of occurrences of a repeating event per unit time. + + + + + + + position in three-dimensional space. **DEPRECATED** in Version 1.1. + + + + + + + length of an object. + + + + + + + level of a resource. **DEPRECATED** in *Version 1.2*. See + `FILL_LEVEL`. + + + + + + + {{term(force)}} applied to a mass in one direction only. + + + + + + + actual versus the standard rating of a piece of equipment. + + + + + + + mass of an object(s) or an amount of material. + + + + + + + feedrate for the axes, or a single axis, associated with a + {{block(Path)}} component. + + + + + + + feedrate for the axes, or a single axis. + + + + + + + position of a control point associated with a {{block(Controller)}} + or a {{block(Path)}}. + + + + + + + acidity or alkalinity of a solution. + + + + + + + point along an axis in a {{term(cartesian coordinate system)}}. + + + + + + + ratio of real power flowing to a load to the apparent power in that + AC circuit. + + + + + + + force per unit area measured relative to atmospheric pressure. + Commonly referred to as gauge pressure. + + + + + + + amount of time a piece of equipment has performed different types of + activities associated with the process being performed at that piece + of equipment. + + + + + + + degree to which a substance opposes the passage of an electric + current. + + + + + + + rotational speed of a rotary axis. + + + + + + + sound level or sound pressure level relative to atmospheric + pressure. + + + + + + + rotational speed of the rotary axis. **DEPRECATED** in *Version + 1.2*. Replaced by `ROTARY_VELOCITY`. + + + + + + + amount of deformation per unit length of an object when a load is + applied. + + + + + + + degree of hotness or coldness measured on a definite scale. + + + + + + + force that stretches or elongates an object. + + + + + + + angular displacement. + + + + + + + turning force exerted on an object or by an object. + + + + + + + rate of change of position of a {{block(Component)}}. + + + + + + + fluid's resistance to flow. + + + + + + + electrical potential between two points. **DEPRECATED** in *Version + 1.6*. Replaced by `VOLTAGE_AC` and `VOLTAGE_DC`. + + + + + + + apparent power in an electrical circuit, equal to the product of + root-mean-square (RMS) voltage and RMS current (commonly referred to + as VA). + + + + + + + reactive power in an AC electrical circuit (commonly referred to as + VAR). + + + + + + + fluid volume of an object or container. + + + + + + + geometric volume of an object or container. + + + + + + + power flowing through or dissipated by an electrical circuit or + piece of equipment. + + + + + + + electrical current that reverses direction at regular short + intervals. + + + + + + + electric current flowing in one direction only. + + + + + + + electrical potential between two points in an electrical circuit in + which the current periodically reverses direction. + + + + + + + electrical potential between two points in an electrical circuit in + which the current is unidirectional. + + + + + + + dimension of an entity relative to the X direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Y direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Z direction of the referenced + coordinate system. + + + + + + + dimension of a diameter. + + + + + + + angular position of a plane or vector relative to a {{term(cartesian + coordinate system)}} + + + + + + + amount of water vapor present expressed as a percent to reach + saturation at the same temperature. + + + + + + + amount of water vapor expressed in grams per cubic meter. + + + + + + + ratio of the water vapor present over the total weight of the water + vapor and air present expressed as a percent. + + + + + + + average rate of change of values for data items in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + average rate of change of values for assets in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + change of pressure per unit time. + + + + + + + negative rate of change of velocity. + + + + + + + negative rate of change of angular velocity. + + + + + + + force per unit area measured relative to a vacuum. + + + + + + + percentage open where 100% is fully open and 0% is fully closed. + + + + + + + temperature at which moisture begins to condense, corresponding to + saturation for a given absolute humidity. + + + + + + + force relative to earth's gravity. + + + + + + + acceleration relative to Earth's gravity of 9.80665 + `METER/SECOND^2`. + + + + + + + maximum rated charge a battery is capable of maintaining based on + the battery discharging at a specified current over a specified time + period. + + + + + + + value of current being drawn from the {{block(Component)}}. + + + + + + + value of the current being supplied to the {{block(Component)}} for + the purpose of charging. + + + + + + + value of the battery's present capacity expressed as a + percentage of the battery's maximum rated capacity. + + + + + + + difference between actual and commanded position at the end of a + motion. + + + + + + + difference between actual and commanded position at any specific + point in time during a motion. + + + + + + + difference between the commanded encoder/resolver position, and the + actual encoder/resolver position when motion is complete. + + + + + + + angular difference between the commanded encoder/resolver position, + and the actual encoder/resolver position when motion is complete. + + + + + + + difference between the commanded encoder/resolver position and the + actual encoder/resolver position at any specified point in time + during a motion. + + + + + + + angular difference between the commanded encoder/resolver position + and the actual encoder/resolver position at any specified point in + time during a motion. + + + + + + + absolute value of the change in position along a vector. + + + + + + + absolute value of the change in angular position around a vector + + + + + + + point in a {{term(cartesian coordinate system)}}. + + + + + + + set of axes currently associated with a {{block(Path)}} or + {{block(Controller)}}. + + + + + + + operational state of an apparatus for moving or controlling a + mechanism or system. + + + + + + + **DEPRECATED:** Replaced with `CONDITION` category data items in + Version 1.1.0. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been added or + changed. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been removed. + + + + + + + {{term(agent)}}'s ability to communicate with the data source. + + + + + + + describes the way the axes will be associated to each other. This is + used in conjunction with `COUPLED_AXES` to indicate the way they are + interacting. + + + + + + + value of a signal or calculation issued to adjust the feedrate of an + individual linear type axis. + + + + + + + state of the axis lockout function when power has been removed and + the axis is allowed to move freely. + + + + + + + state of a {{block(Linear)}} or {{block(Rotary)}} component + representing an axis. + + + + + + + line of code or command being executed by a {{block(Controller)}} + entity. + + + + + + + total count of the number of blocks of program code that have been + executed since execution started. + + + + + + + state of an interlock function or control logic state intended to + prevent the associated {{block(Chuck)}} component from being + operated. + + + + + + + operating state of a mechanism that holds a part or stock material + during a manufacturing process. It may also represent a mechanism + that holds any other mechanism in place within a piece of equipment. + + + + + + + programmatic code being executed. **DEPRECATED** in *Version 1.1*. + + + + + + + operating state of a mechanism represented by a + {{block(Composition)}} entity. + + + + + + + current mode of the {{block(Controller)}} component. + + + + + + + setting or operator selection that changes the behavior of a piece + of equipment. + + + + + + + set of associated axes. + + + + + + + time and date code associated with a material or other physical + item. + + + + + + + identifier of another piece of equipment that is temporarily + associated with a component of this piece of equipment to perform a + particular function. + + + + + + + direction of motion. + + + + + + + operational state of a {{block(Door)}} component or composition + element. + + + + + + + state of the emergency stop signal for a piece of equipment, + controller path, or any other component or subsystem of a piece of + equipment. + + + + + + + indication of whether the end of a piece of bar stock being feed by + a bar feeder has been reached. + + + + + + + indication that a piece of equipment, or a sub-part of a piece of + equipment, is performing specific types of activities. + + + + + + + operating state of a {{block(Component)}}. + + + + + + + current intended production status of the {{block(Component)}}. + + + + + + + hardness of a material. + + + + + + + current line of code being executed. **DEPRECATED** in *Version + 1.4.0*. + + + + + + + identifier for a {{block(Block)}} of code in a {{block(Program)}}. + + + + + + + position of a block of program code within a control program. + + + + + + + identifier of a material used or consumed in the manufacturing + process. + + + + + + + identifies the layers of material applied to a part or product as + part of an additive manufacturing process. + + + + + + + information to be transferred from a piece of equipment to a client + software application. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + identifier for a pallet. + + + + + + + aggregate count of parts. + + + + + + + indication designating whether a part or work piece has been + detected or is present. + + + + + + + identifier of a part in a manufacturing operation. + + + + + + + identifier of a part or product moving through the manufacturing + process. **DEPRECATED** in *Version 1.7*. `PART_NUMBER` is now a + `subType` of `PART_KIND_ID`. + + + + + + + value of a signal or calculation issued to adjust the feedrate for + the axes associated with a {{block(Path)}} component that may + represent a single axis or the coordinated movement of multiple + axes. + + + + + + + describes the operational relationship between a {{block(Path)}} + entity and another {{block(Path)}} entity for pieces of equipment + comprised of multiple logical groupings of controlled axes or other + logical operations. + + + + + + + indication of the status of the source of energy for an entity to + allow it to perform its intended function or the state of an + enabling signal providing permission for the entity to perform its + functions. + + + + + + + status of the {{block(Component)}}. **DEPRECATED** in *Version + 1.1.0*. + + + + + + + time and date associated with an activity or event. + + + + + + + name of the logic or motion program being executed by the + {{block(Controller)}} component. + + + + + + + comment or non-executable statement in the control program. + + + + + + + indication of the status of the {{block(Controller)}} components + program editing mode. A program may be edited while another is + executed. + + + + + + + name of the program being edited. This is used in conjunction with + {{block(ProgramEdit)}} when in `ACTIVE` state. + + + + + + + non-executable header section of the control program. + + + + + + + {{term(URI)}} for the source file associated with + {{block(Program)}}. + + + + + + + defines whether the logic or motion program defined by + {{block(Program)}} is being executed from the local memory of the + controller or from an outside source. + + + + + + + indication of the nesting level within a control program that is + associated with the code or instructions that is currently being + executed. + + + + + + + current operating mode for a {{block(Rotary)}} type axis. + + + + + + + percentage change to the velocity of the programmed velocity for a + {{block(Rotary)}} axis. + + + + + + + serial number associated with a {{block(Component)}}, + {{block(Asset)}}, or {{block(Device)}}. + + + + + + + indication of the status of the spindle for a piece of equipment + when power has been removed and it is free to rotate. + + + + + + + identifier of an individual tool asset. + + + + + + + identifier for the tool group associated with a specific tool. + Commonly used to designate spare tools. + + + + + + + identifier of the tool currently in use for a given `Path`. + **DEPRECATED** in *Version 1.2.0*. See `TOOL_ASSET_ID`. + + + + + + + identifier assigned by the {{block(Controller)}} component to a + cutting tool when in use by a piece of equipment. + + + + + + + reference to the tool offset variables applied to the active cutting + tool. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + data whose meaning may change over time due to changes in the + operation of a piece of equipment or the process being executed on + that piece of equipment. + + + + + + + indication of the reason that {{block(Execution)}} is reporting a + value of `WAIT`. + + + + + + + identifier for the type of wire used as the cutting mechanism in + Electrical Discharge Machining or similar processes. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. **DEPRECATION WARNING**: Recommend using + `FIXTURE_ID` instead. + + + + + + + reference to offset variables for a work piece or part. + + + + + + + Operating System (OS) of a {{block(Component)}}. + + + + + + + embedded software of a {{block(Component)}} . + + + + + + + application on a {{block(Component)}}. + + + + + + + software library on a {{block(Component)}} + + + + + + + hardware of a {{block(Component)}}. + + + + + + + network details of a {{block(Component)}}. + + + + + + + three space angular displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + three space linear displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + {{term(UUID)}} of new device added to an {{term(MTConnect Agent)}}. + + + + + + + {{term(UUID)}} of a device removed from an {{term(MTConnect + Agent)}}. + + + + + + + {{term(UUID)}} of the device whose {{term(metadata)}} has changed. + + + + + + + status of the connection between an {{term(adapter)}} and an + {{term(agent)}}. + + + + + + + originator’s software version of the {{term(adapter)}}. + + + + + + + {{term(URI)}} of the {{term(adapter)}}. + + + + + + + reference version of the MTConnect Standard supported by the + {{term(adapter)}}. + + + + + + + {{term(attachment)}} between a sensor and an entity. + + + + + + + state or condition of a part. + + + + + + + identifier of a process being executed by the device. + + + + + + + identifier given to link the individual occurrence to a group of + related occurrences, such as a process step in a process plan. + + + + + + + identifier given to link the individual occurrence to a class of + processes or process definition. + + + + + + + identifier given to a collection of individual parts. + + + + + + + identifier given to link the individual occurrence to a class of + parts, typically distinguished by a particular part design. + + + + + + + identifier given to a distinguishable, individual part. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. **DEPRECATION WARNING**. Recommend using + `CONTROL_LIMITS`. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. **DEPRECATION WARNING**. Recommend using + `SPECIFICATION_LIMITS`. + + + + + + + set of limits used to trigger warning or alarm indicators. + **DEPRECATION WARNING**. Recommend using `ALARM_LIMITS`. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, load materials, parts, or other items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, unload materials, parts, or other + items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, transfer materials, parts, or other + items from one location to another. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, activate or be performed. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, deactivate or cease. + + + + + + + accumulation of the number of times a cyclic function has attempted + to, or is planned to attempt to execute. + + + + + + + state of a valve is one of open, closed, or transitioning between + the states. + + + + + + + state or operating mode of a {{block(Lock)}}. + + + + + + + particular condition of the process occurrence at a specific time. + + + + + + + particular condition of the part occurrence at a specific time. + + + + + + + state of {{block(Component)}} or {{block(Composition)}} that + describes the automatic or manual operation of the entity. + + + + + + + {{term(data set)}} of the number of {{termplural(Asset)}} of a given + type for a {{term(Device)}}. + + + + + + + actions or activities to be performed in support of a piece of + equipment. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. + + + + + + + interpretation of `PART_COUNT`. + + + + + + + time provided by a timing device at a specific point in time. + + + + + + + name of the host computer supplying data. + + + + + + + number of the TCP/IP or UDP/IP port for the connection endpoint. + + + + + + + indication designating whether a leak has been detected. + + + + + + + present status of the battery. + + + + + + + {{term(UUID)}} of a {{term(feature)}}. {{cite(ISO 10303 AP + 242/239)}}. + + + + + + + detection result of a sensor. + + + + + + + {{block(Event)}} that represents a {{block(Component)}} where the + {{block(EntryDefinition)}} identifies the {{block(Component)}} and + the {{block(CellDefinition)}}s define the + {{block(Component)}}'s observed {{block(DataItem)}}s. + + + + + + + properties of each addressable work offset. + + + + + + + properties of each addressable tool offset. + + + + + + + assessing elements of a {{term(feature)}}. + + + + + + + {{term(UUID)}} of the {{term(characteristic)}}. + + + + + + + class of measurement being performed. {{cite(QIF 3:2018 Section + 6.3)}} + + + + + + + measurement based on the measurement type. + + + + + + + engineering units of the measurement. + + + + + + + pass/fail result of the measurement. + + + + + + + method used to compute {{term(standard uncertainty)}}. + + + + + + + {{term(uncertainty)}} specified by {{block(UncertaintyType)}}. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. + + + + + + + set of limits used to trigger warning or alarm indicators. + + + + + + + references the {{block(CuttingToolLifeCycle)}} + {{block(CuttingItem)}} index related to the + {{property(CuttingItem::indices)}} of the currently active cutting + tool edge. + + + + + + + structured information that allows the unambiguous determination of + an object for purposes of identification and location. {{cite(ISO + 19160-4:2017)}} + + + + + + + active energy source for the {{block(Component)}}. + + + + + + + textual description of the location of an object or activity. + + + + + + + dimension between two surfaces of an object, usually the dimension + of smallest measure, for example an additive layer, or a depth of + cut. + + + + + + + absolute geographic location defined by two coordinates, longitude + and latitude and an elevation. + + + + + + + indication that the piece of equipment has experienced a + communications failure. + + + + + + + indication that the value of the data associated with a measured + value or a calculation is outside of an expected range. + + + + + + + indication that an error occurred in the logic program or + programmable logic controller (PLC) associated with a piece of + equipment. + + + + + + + indication that an error occurred in the motion program associated + with a piece of equipment. + + + + + + + general purpose indication associated with an electronic component + of a piece of equipment or a controller that represents a fault that + is not associated with the operator, program, or hardware. + + + + + + + indication of a fault associated with an actuator. + + + + + + + operational state of an {{block(Interface)}}. + + + + + + + operating state of the service to advance material or feed product + to a piece of equipment from a continuous or bulk source. + + + + + + + operating state of the service to change the type of material or + product being loaded or fed to a piece of equipment. + + + + + + + operating state of the service to remove or retract material or + product. + + + + + + + operating state of the service to change the part or product + associated with a piece of equipment to a different part or product. + + + + + + + operating state of the service to load a piece of material or + product. + + + + + + + operating state of the service to unload a piece of material or + product. + + + + + + + operating state of the service to open a chuck. + + + + + + + operating state of the service to open a door. + + + + + + + operating state of the service to close a chuck. + + + + + + + operating state of the service to close a door. + + + + + + + A user variable + + + + + + + + + The types of measurements available + + + + + + + + Extended tyoe for The sub-types for a measurement + + + + + + + + + + The sub-types for a measurement + + + + + + + relating to or derived in the simplest manner from the fundamental + units or measurements. + + + + + + + indication of the operating state of a mechanism. + + + + + + + measured or reported value of an {{term(observation)}}. + + + + + + + all actions, items, or activities being counted independent of the + outcome. + + + + + + + measurement of alternating voltage or current. If not specified + further in statistic, defaults to RMS voltage. **DEPRECATED** in + *Version 1.6*. + + + + + + + A-Scale weighting factor on the frequency scale. + + + + + + + when multiple locations on a piece of bar stock being feed by a bar + feeder are referenced as the indication of whether the end of that + piece of bar stock has been reached. + + + + + + + actions, items, or activities being counted that do not conform to + specification or expectation. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + B-Scale weighting factor on the frequency scale. + + + + + + + directive value including adjustments such as an offset or + overrides. + + + + + + + amount of material consumed from an object or container during a + manufacturing process. + + + + + + + state of the enabling signal or control logic that enables or + disables the function or operation of the entity. + + + + + + + C-Scale weighting factor on the frequency scale. + + + + + + + elapsed time of a temporary halt of action. + + + + + + + DC current or voltage. **DEPRECATED** in *Version 1.6*. + + + + + + + setting or operator selection used to execute a test mode to confirm + the execution of machine functions. + + + + + + + D-Scale weighting factor on the frequency scale. + + + + + + + relating to the expiration or end of useful life for a material or + other physical item. + + + + + + + relating to the first use of a material or other physical item. + + + + + + + actions, items, or activities being counted that conform to + specification or expectation. + + + + + + + relating to or derived from the last {{term(observation)}}. + + + + + + + relating to momentary activation of a function or a movement. + **DEPRECATION WARNING**: May be deprecated in the future. + + + + + + + indication of the position of a mechanism that may move in a lateral + direction. + + + + + + + scale to measure the elasticity of a surface. + + + + + + + reference to a length type tool offset variable. + + + + + + + state of the power source. + + + + + + + direction of motion of a linear motion. + + + + + + + indication that the subparts of a piece of equipment are under load. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + relating to the primary logic or motion program currently being + executed. + + + + + + + relating to maintenance on the piece of equipment. + + + + + + + indication of the state of an operator controlled interlock that can + inhibit the ability to initiate an unclamp action of an + electronically controlled chuck. + + + + + + + related to the production of a material or other physical item. + + + + + + + maximum value. + + + + + + + minimum value. + + + + + + + scale to measure the resistance to scratching of a surface. + + + + + + + indication of the open or closed state of a mechanism. + + + + + + + no weighting factor on the frequency scale. + + + + + + + piece of equipment that is powered or performing any activity. + + + + + + + relating to the person currently responsible for operating the piece + of equipment. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + overridden value. + + + + + + + piece of equipment is powered and functioning or + {{block(Component)}} that are required to remain on are powered. + + + + + + + main or principle. + + + + + + + position provided by a measurement probe. **DEPRECATION WARNING**: + May be deprecated in the future. + + + + + + + relating to production of a part or product on a piece of equipment. + + + + + + + directive value without offsets and adjustments. + + + + + + + reference to a radial type tool offset variable. + + + + + + + performing an operation faster or in less time than nominal rate. + + + + + + + remaining measure or count of an action, object or activity. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + direction of a rotary motion using the right hand rule convention. + + + + + + + identity of a control program that is used to specify the order of + execution of other programs. + + + + + + + relating to the preparation of a piece of equipment for production + or restoring the piece of equipment to a neutral state after + production. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + standard measure of an object or an action. + + + + + + + boundary when an activity or an event commences. + + + + + + + indication of the activation state of a mechanism represented by a + {{block(Composition)}}. + + + + + + + goal of the operation or process. + + + + + + + relating to the end or completion of an activity or event. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + remaining usable measure of an object or action. + + + + + + + indication of the position of a mechanism that may move in a + vertical direction. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + piece of equipment performing any activity, the equipment is active + and performing a function under load or not. + + + + + + + IPV4 network address of the {{block(Component)}}. + + + + + + + IPV6 network address of the {{block(Component)}}. + + + + + + + Gateway for the {{block(Component)}} network. + + + + + + + SubNet mask for the {{block(Component)}} network. + + + + + + + layer2 Virtual Local Network (VLAN) ID for the {{block(Component)}} + network. + + + + + + + Media Access Control Address. The unique physical address of the + network hardware. + + + + + + + identifies whether the connection type is wireless. + + + + + + + license code to validate or activate the hardware or software. + + + + + + + version of the hardware or software. + + + + + + + date the hardware or software was released for general use. + + + + + + + date the hardware or software was installed. + + + + + + + corporate identity for the maker of the hardware or software. + + + + + + + universally unique identifier as specified in ISO 11578 or RFC 4122. + + + + + + + serial number that uniquely identifies a specific part. + + + + + + + material that is used to produce parts. + + + + + + + group of parts tracked as a lot. + + + + + + + group of parts produced in a batch. + + + + + + + material heat number. + + + + + + + particular part design or model. + + + + + + + group of parts having similarities in geometry, manufacturing + process, and/or functions. + + + + + + + word or set of words by which a part is known, addressed, or + referred to. + + + + + + + step in the process plan that this occurrence corresponds to. + + + + + + + process plan that a process occurrence belongs to. + + + + + + + authorization of a process occurrence. + + + + + + + word or set of words by which a process being executed (process + occurrence) by the device is known, addressed, or referred to. + + + + + + + reference to a ISO 10303 Executable. + + + + + + + associated with the completion of an activity or event. + + + + + + + relating to logic or motion program currently executing. + + + + + + + actions or activities that were attempted , but failed to complete + or resulted in an unexpected or unacceptable outcome. + + + + + + + actions or activities that were attempted, but terminated before + they could be completed. + + + + + + + boundary when an activity or an event terminates. + + + + + + + amount discarded. + + + + + + + amount included in the {{term(part)}}. + + + + + + + {{term(request)}} by an {{block(Interface)}} for a task. + + + + + + + {{term(response)}} by an {{block(Interface)}} to a {{term(request)}} + for a task. + + + + + + + phase or segment of a recipe or program. + + + + + + + phase of a recipe process. + + + + + + + process as part of product production; can be a subprocess of a + larger process. + + + + + + + step of a discrete manufacturing process. + + + + + + + observed as a binary data type. + + + + + + + observed as a boolean data type. + + + + + + + observed as a set containing a restricted number of discrete values + where each discrete value is named and unique. {{cite(ISO + 21961:2003, 013)}} + + + + + + + indicated by the presence or existence of something. + + + + + + + model info of the hardware or software. + + + + + + + + + The sub-types for a measurement + + + + + + + + Extended tyoe for Statistical operations on data + + + + + + + + + + Statistical operations on data + + + + + + + mathematical average value calculated for the data item during the + calculation period. + + + + + + + **DEPRECATED** in *Version 1.6*. ~~A measure of the + "peakedness" of a probability distribution; i.e., the + shape of the distribution curve.~~ + + + + + + + maximum or peak value recorded for the data item during the + calculation period. + + + + + + + middle number of a series of numbers. + + + + + + + minimum value recorded for the data item during the calculation + period. + + + + + + + number in a series of numbers that occurs most often. + + + + + + + difference between the maximum and minimum value of a data item + during the calculation period. Also represents Peak-to-Peak + measurement in a waveform. + + + + + + + mathematical Root Mean Square (RMS) value calculated for the data + item during the calculation period. + + + + + + + statistical Standard Deviation value calculated for the data item + during the calculation period. + + + + + + + + + Statistical operations on data + + + + + + + + Extended tyoe for same as {{property(DataItem::units)}}. See + {{package(Device Information Model)}}. + + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + + Extended tyoe for The units supported for the source equipment that can + be converted into MTC Units. + + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + measure of viscosity. + + + + + + + rotational velocity in degrees per minute. + + + + + + + temperature in Fahrenheit. + + + + + + + feet. + + + + + + + feet per minute. + + + + + + + feet per second. + + + + + + + acceleration in feet per second squared. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in feet. + + + + + + + gallons per minute. + + + + + + + measurement of time in hours. + + + + + + + inches. + + + + + + + inches per minute. + + + + + + + inches per second. + + + + + + + acceleration in inches per second squared. + + + + + + + measure of torque in inch pounds. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in inches. + + + + + + + measurement of temperature. + + + + + + + measurement in kilowatt. + + + + + + + kilowatt hours which is 3.6 mega joules. + + + + + + + measurement of rate of flow of a fluid. + + + + + + + velocity in millimeters per minute. + + + + + + + measurement of time in minutes. + + + + + + + unsupported unit. + + + + + + + US pounds. + + + + + + + pressure in pounds per square inch (PSI). + + + + + + + angle in radians. + + + + + + + velocity in radians per minute. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + pressure in Bar. + + + + + + + pressure in Torr. + + + + + + + pressure in Millimeter of Mercury (mmHg). + + + + + + + pascal per minute. + + + + + + + $$MASS\times GRAVITATIONAL_ACCELERATION$$ (g) given in + `METER/SECOND^2`. + + + + + + + acceleration relative to earth's gravity given in + `METER/SECOND^2`. > Note 1 to entry: At different points on + Earth's surface, the free-fall acceleration ranges from 9.764 + to 9.834 m/s2 (Wikipedia: Gravitational Acceleration). The constant + can be customized depending on the location in the universe. > + Note 2 to entry: In the standard, it is assumed that Earth's + average value of gravitational acceleration is 9.90665 m/s2. + + + + + + + electric charge in ampere hour. + + + + + + + change of geometric volume in cubic foot per hour. + + + + + + + change of geometric volume in cubic foot per minute. + + + + + + + geometric area in inches. + + + + + + + geometric volume in feet. + + + + + + + inch per revolution. + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + + The coordinate system to be used for the position + + + + + + + unchangeable coordinate system that has machine zero as its origin. + + + + + + + coordinate system that represents the working area for a particular + workpiece whose origin is shifted within the `MACHINE` coordinate + system. If the `WORK` coordinates are not currently defined in the + piece of equipment, the `MACHINE` coordinates will be used. + + + + + + + + + Extended tyoe for The reset intervals + + + + + + + + + + The reset intervals + + + + + + + {{term(observation)}} of the {{block(DataItem)}} that is measuring + an action or operation is to be reset upon completion of that action + or operation. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 12-month period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 24-hour period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is not reset and + accumulates for the entire life of the piece of equipment. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset upon + completion of a maintenance event. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a monthly period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset when + power was applied to the piece of equipment after a planned or + unplanned interruption of power has occurred. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a work shift. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 7-day period. + + + + + + + + + The reset intervals + + + + + + + + + The document version + + + + + + + time the file was created. + + + + + + + Indicates that this was a test document + + + + + + + The unique instance identifier of this agent process + + + + + + + The sender of the message + + + + + + + A timestamp in 8601 format of the last update of the Device + information for any device + + + + + + + + The number of assets + + + + + + + + + + + indicates if the MTConnect Agent is validating against the normative + model. + + + + + + + + {{block(AssetCounts)}} groups {{block(AssetCount)}} entities. + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + The type of asset + + + + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the data + management within the {{term(agent)}}. + + + + + + + {{block(AssetCounts)}} groups {{block(AssetCount)}} entities. + + + + + + + + + The size of the agent's buffer. + + + + + + + The maximum number of assets + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + indicates if the MTConnect Agent is validating against the normative + model. + + + + + + + + root entity of an {{term(MTConnectDevices Response Document)}} that + contains the {{term(Device Information Model)}} of one or more + {{block(Device)}} entities. + ![MTConnectDevices](figures/MTConnectDevices.png + "MTConnectDevices"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectDevices)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the + data management within the {{term(agent)}}. + + + + + + + This section provides semantic information for the {{block(Device)}} + types. + + + + + + + + + The station id for this device + + + + + + + + The ISO 841 classification for the device + + + + + + + + The model name + + + + + + + + This section provides semantic information for the {{block(Device)}} + types. + + + + + + + Description + + + + + + + Description + + + + + + + + + Description + + + + + + + See {{sect(Description)}}. + + + + + + + technical information about an entity describing its physical + layout, functional characteristics, and relationships with other + entities. + + + + + + + + + + + + {{block(Components)}} groups one or more {{block(Component)}} + entities. + + + + + + + Compositions Model + + + + + + + References Model + + + + + + + + unique identifier for the power source. + + + + + + + The device manufacturer component name + + + + + + + The rate at which the data is sampled from the component + + + + + + + DEPRECATED: The rate at which the data is sampled from the component + + + + + + + + Description + + + + + + + The descriptive information. This can be manufacturer specific + + + + + + + The content of the description can text or XML elements + + + + + + + + name of the material manufacturer. + + + + + + + The model + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + leaf {{block(Component)}} composed of a storage or mounting location + for a tool associated with a {{block(Turret)}}, + {{block(GangToolBar)}}, or {{block(ToolRack)}}. + + + + + + + + An abstract component that has an optional uuid + + + + + + + + The component's universally unique id. + + + + + + + identifier of the maintenance activity. + + + + + + + + + + An abstract component that has an optional uuid + + + + + + + {{block(Components)}} groups one or more {{block(Component)}} entities. + + + + + + + + + + Description + + + + + + + + DEPRECATED: The device's ISO-841 classification + + + + + + + The components universally unique id. This can be composed of the + manufactures id or name and the serial number. + + + + + + + identifier of the maintenance activity. + + + + + + + MTConnect version of the {{term(Device Information Model)}} used + to configure the information to be published for a piece of + equipment in an {{term(MTConnect Response Document)}}. + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + abstract {{block(Component)}} composed of removable part(s) of a piece + of equipment that provides supplementary or extended functionality. + + + + + + + + + + abstract {{block(Component)}} composed of removable part(s) of a piece + of equipment that provides supplementary or extended functionality. + + + + + + + See {{sect(Axis)}}. + + + + + + + + + + See {{sect(Axis)}}. + + + + + + + {{block(Loader)}} that delivers bar stock to a piece of equipment. + + + + + + + + + + {{block(Loader)}} that delivers bar stock to a piece of equipment. + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(System)}} that provides distribution and management of fluids + that remove heat from a piece of equipment. + + + + + + + + + + {{block(System)}} that provides distribution and management of fluids + that remove heat from a piece of equipment. + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(Component)}} that observes the surroundings of another + {{block(Component)}}. > Note: {{block(Environmental)}} **SHOULD** be + organized by {{block(Auxillaries)}}, {{block(Systems)}} or + {{block(Parts)}} depending on the relationship to the + {{block(Component)}}. + + + + + + + + + + {{block(Component)}} that observes the surroundings of another + {{block(Component)}}. > Note: {{block(Environmental)}} **SHOULD** be + organized by {{block(Auxillaries)}}, {{block(Systems)}} or + {{block(Parts)}} depending on the relationship to the + {{block(Component)}}. + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(System)}} that provides movement and distribution of pressurized + liquid throughout the piece of equipment. + + + + + + + + + + {{block(System)}} that provides movement and distribution of pressurized + liquid throughout the piece of equipment. + + + + + + + {{block(Component Types::Axis)}} that provides prismatic motion along a + fixed axis. + + + + + + + + + + {{block(Component Types::Axis)}} that provides prismatic motion along a + fixed axis. + + + + + + + {{block(Auxiliary)}} that provides movement and distribution of + materials, parts, tooling, and other items to or from a piece of + equipment. + + + + + + + + + + {{block(Auxiliary)}} that provides movement and distribution of + materials, parts, tooling, and other items to or from a piece of + equipment. + + + + + + + {{block(System)}} that provides distribution and management of fluids + used to lubricate portions of the piece of equipment. + + + + + + + + + + {{block(System)}} that provides distribution and management of fluids + used to lubricate portions of the piece of equipment. + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(Resource)}} composed of an individual or individuals who either + control, support, or otherwise interface with a piece of equipment. + + + + + + + + + + {{block(Resource)}} composed of an individual or individuals who either + control, support, or otherwise interface with a piece of equipment. + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(Power)}} was **DEPRECATED** in *MTConnect Version 1.1* and was + replaced by {{block(Availability)}} data item type. + + + + + + + + + + {{block(Power)}} was **DEPRECATED** in *MTConnect Version 1.1* and was + replaced by {{block(Availability)}} data item type. + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + abstract {{block(Component)}} composed of material or personnel involved + in a manufacturing process. + + + + + + + + + + abstract {{block(Component)}} composed of material or personnel involved + in a manufacturing process. + + + + + + + {{block(Component Types::Axis)}} that provides rotation about a fixed + axis. + + + + + + + + + + {{block(Component Types::Axis)}} that provides rotation about a fixed + axis. + + + + + + + This section provides semantic information for the + {{block(SensorConfiguration)}} entity. {{term(sensor)}} is a unique type + of a piece of equipment. A {{term(sensor)}} is typically comprised of + two major components: a {{term(sensor unit)}} that provides signal + processing, conversion, and communications and the {{termplural(sensing + element)}} that provides a signal or measured value. The {{term(sensor + unit)}} is modeled as a {{term(lower level)}} {{block(Component)}} + called {{block(Sensor)}}. The {{term(sensing element)}} may be modeled + as a {{block(Composition)}} element of a {{block(Sensor)}} element and + the measured value would be modeled as a {{block(DataItem)}} (See + {{sect(DataItems)}} for more information on {{block(DataItem)}} + elements). Each {{term(sensor unit)}} may have multiple + {{termplural(sensing element)}}; each representing the data for a + variety of measured values. ![Sensing Element provided as a DataItem + Example](figures/Sensing%20Element%20provided%20as%20a%20DataItem%20Example.png "Sensing Element provided as a DataItem Example"){: width="0.8"} > Note: See {{lst(example-of-sensing-element-provided-as-data-item-associated-with-a-component)}} for an {{term(XML)}} example. When a {{term(sensor unit)}} is modeled as a {{block(Component)}} or as a separate piece of equipment, it may provide additional configuration information for the {{termplural(sensor element)}} and the {{term(sensor unit)}} itself. ![Sensor for Rotary Axis Example](figures/Sensor%20for%20Rotary%20Axis%20Example.png "Sensor for Rotary Axis Example"){: width="0.8"} > Note: If a {{block(Sensor)}} provides vibration measurement data for the spindle on a piece of equipment, it could be modeled as a {{block(Sensor)}} for rotary axis named `C`. See {{lst(example-of-sensor-for-rotary-axis)}} for an {{term(XML)}} example. ![Sensor unit with Sensing Elements Example](figures/Sensor%20unit%20with%20Sensing%20Elements%20Example.png "Sensor unit with Sensing Elements Example"){: width="0.8"} > Note: If a {{block(Sensor)}} provides measurement data for multiple {{block(Component)}} elements within a piece of equipment and is not associated with any particular {{block(Component)}}, it **MAY** be modeled as an independent {{block(Component)}} and the data associated with measurements are associated with their associated {{block(Component)}} entities. See {{lst(example-of-sensor-unit-with-sensing-element)}} for an {{term(XML)}} example. {{block(Configuration)}} data provides information required for maintenance and support of the sensor. When {{block(Sensor)}} represents the {{term(sensor unit)}} for multiple {{term(sensing element)}}(s), each sensing element is represented by a {{block(Channel)}}. The {{term(sensor unit)}} itself and each {{block(Channel)}} representing one {{term(sensing element)}} **MAY** have its own configuration data. ![Sensor Configuration Example](figures/Sensor%20Configuration%20Example.png "Sensor Configuration Example"){: width="0.8"} > Note: See {{lst(example-of-configuration-data-for-sensor)}} for an {{term(XML)}} example. + + + + + + + + + + This section provides semantic information for the + {{block(SensorConfiguration)}} entity. {{term(sensor)}} is a unique type + of a piece of equipment. A {{term(sensor)}} is typically comprised of + two major components: a {{term(sensor unit)}} that provides signal + processing, conversion, and communications and the {{termplural(sensing + element)}} that provides a signal or measured value. The {{term(sensor + unit)}} is modeled as a {{term(lower level)}} {{block(Component)}} + called {{block(Sensor)}}. The {{term(sensing element)}} may be modeled + as a {{block(Composition)}} element of a {{block(Sensor)}} element and + the measured value would be modeled as a {{block(DataItem)}} (See + {{sect(DataItems)}} for more information on {{block(DataItem)}} + elements). Each {{term(sensor unit)}} may have multiple + {{termplural(sensing element)}}; each representing the data for a + variety of measured values. ![Sensing Element provided as a DataItem + Example](figures/Sensing%20Element%20provided%20as%20a%20DataItem%20Example.png "Sensing Element provided as a DataItem Example"){: width="0.8"} > Note: See {{lst(example-of-sensing-element-provided-as-data-item-associated-with-a-component)}} for an {{term(XML)}} example. When a {{term(sensor unit)}} is modeled as a {{block(Component)}} or as a separate piece of equipment, it may provide additional configuration information for the {{termplural(sensor element)}} and the {{term(sensor unit)}} itself. ![Sensor for Rotary Axis Example](figures/Sensor%20for%20Rotary%20Axis%20Example.png "Sensor for Rotary Axis Example"){: width="0.8"} > Note: If a {{block(Sensor)}} provides vibration measurement data for the spindle on a piece of equipment, it could be modeled as a {{block(Sensor)}} for rotary axis named `C`. See {{lst(example-of-sensor-for-rotary-axis)}} for an {{term(XML)}} example. ![Sensor unit with Sensing Elements Example](figures/Sensor%20unit%20with%20Sensing%20Elements%20Example.png "Sensor unit with Sensing Elements Example"){: width="0.8"} > Note: If a {{block(Sensor)}} provides measurement data for multiple {{block(Component)}} elements within a piece of equipment and is not associated with any particular {{block(Component)}}, it **MAY** be modeled as an independent {{block(Component)}} and the data associated with measurements are associated with their associated {{block(Component)}} entities. See {{lst(example-of-sensor-unit-with-sensing-element)}} for an {{term(XML)}} example. {{block(Configuration)}} data provides information required for maintenance and support of the sensor. When {{block(Sensor)}} represents the {{term(sensor unit)}} for multiple {{term(sensing element)}}(s), each sensing element is represented by a {{block(Channel)}}. The {{term(sensor unit)}} itself and each {{block(Channel)}} representing one {{term(sensing element)}} **MAY** have its own configuration data. ![Sensor Configuration Example](figures/Sensor%20Configuration%20Example.png "Sensor Configuration Example"){: width="0.8"} > Note: See {{lst(example-of-configuration-data-for-sensor)}} for an {{term(XML)}} example. + + + + + + + Description + + + + + + + + + + Description + + + + + + + abstract {{block(Component)}} that is permanently integrated into the + piece of equipment. + + + + + + + + + + abstract {{block(Component)}} that is permanently integrated into the + piece of equipment. + + + + + + + {{block(Auxiliary)}} that manages, positions, stores, and delivers + tooling within a piece of equipment. + + + + + + + + + + {{block(Auxiliary)}} that manages, positions, stores, and delivers + tooling within a piece of equipment. + + + + + + + {{block(Auxiliary)}} that removes manufacturing byproducts from a piece + of equipment. + + + + + + + + + + {{block(Auxiliary)}} that removes manufacturing byproducts from a piece + of equipment. + + + + + + + {{block(Component)}} composed of part(s) comprising the rigid bodies of + the piece of equipment. + + + + + + + + + + {{block(Component)}} composed of part(s) comprising the rigid bodies of + the piece of equipment. + + + + + + + {{block(Structure)}} that provides a connection between + {{block(Component)}} entities. + + + + + + + + + + {{block(Structure)}} that provides a connection between + {{block(Component)}} entities. + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + abstract {{block(Component)}} composed of a manufacturing process being + executed on a piece of equipment. + + + + + + + + + + abstract {{block(Component)}} composed of a manufacturing process being + executed on a piece of equipment. + + + + + + + Description + + + + + + + + + + Description + + + + + + + Example + + + + + + + + + + Example + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(System)}} that evacuates gases and liquids from an enclosed and + sealed space to a controlled negative pressure or a molecular density + below the prevailing atmospheric level. + + + + + + + + + + {{block(System)}} that evacuates gases and liquids from an enclosed and + sealed space to a controlled negative pressure or a molecular density + below the prevailing atmospheric level. + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + abstract {{block(Component)}} composed of a {{term(part)}} being + processed by a piece of equipment. + + + + + + + + + + abstract {{block(Component)}} composed of a {{term(part)}} being + processed by a piece of equipment. + + + + + + + {{block(Component)}} that physically prohibits a {{block(Device)}} or + {{block(Component)}} from opening or operating. + + + + + + + + + + {{block(Component)}} that physically prohibits a {{block(Device)}} or + {{block(Component)}} from opening or operating. + + + + + + + {{block(Component)}} that provides an axis of rotation for the purpose + of rapidly rotating a part or a tool to provide sufficient surface speed + for cutting operations. {{block(Spindle)}} was **DEPRECATED** in + *MTConnect Version 1.1* and was replaced by {{block(RotaryMode)}}. + + + + + + + + + + {{block(Component)}} that provides an axis of rotation for the purpose + of rapidly rotating a part or a tool to provide sufficient surface speed + for cutting operations. {{block(Spindle)}} was **DEPRECATED** in + *MTConnect Version 1.1* and was replaced by {{block(RotaryMode)}}. + + + + + + + {{block(Component)}} composed of a sensor or an instrument that measures + temperature. {{block(Thermostat)}} was **DEPRECATED** in *MTConnect + Version 1.2* and was replaced by {{block(Temperature)}}. + + + + + + + + + + {{block(Component)}} composed of a sensor or an instrument that measures + temperature. {{block(Thermostat)}} was **DEPRECATED** in *MTConnect + Version 1.2* and was replaced by {{block(Temperature)}}. + + + + + + + {{block(Component)}} composed of a sensor or an instrument that measures + the amount and/or frequency of vibration within a system. + {{block(Vibration)}} was **DEPRECATED** in *MTConnect Version 1.2* and + was replaced by {{block(Displacement)}}, {{block(Frequency)}} etc. + + + + + + + + + + {{block(Component)}} composed of a sensor or an instrument that measures + the amount and/or frequency of vibration within a system. + {{block(Vibration)}} was **DEPRECATED** in *MTConnect Version 1.2* and + was replaced by {{block(Displacement)}}, {{block(Frequency)}} etc. + + + + + + + leaf {{block(Component)}} composed of a mechanism that holds a part or + stock material in place. + + + + + + + + + + leaf {{block(Component)}} composed of a mechanism that holds a part or + stock material in place. + + + + + + + leaf {{block(Component)}} that produces a current of air. + + + + + + + + + + leaf {{block(Component)}} that produces a current of air. + + + + + + + leaf {{block(Component)}} that flattens or spreading materials. + + + + + + + + + + leaf {{block(Component)}} that flattens or spreading materials. + + + + + + + leaf {{block(Component)}} composed of a mechanism or wheel that turns in + a frame or block and serves to change the direction of or to transmit + force. + + + + + + + + + + leaf {{block(Component)}} composed of a mechanism or wheel that turns in + a frame or block and serves to change the direction of or to transmit + force. + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is + awaiting transfer from a {{block(ToolMagazine)}} to {{term(spindle)}} or + {{block(Turret)}}. + + + + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is + awaiting transfer from a {{block(ToolMagazine)}} to {{term(spindle)}} or + {{block(Turret)}}. + + + + + + + leaf {{block(Component)}} that provides power to electric mechanisms. + + + + + + + + + + leaf {{block(Component)}} that provides power to electric mechanisms. + + + + + + + leaf {{block(Component)}} that allows material to flow for the purpose + of drainage from, for example, a vessel or tank. + + + + + + + + + + leaf {{block(Component)}} that allows material to flow for the purpose + of drainage from, for example, a vessel or tank. + + + + + + + leaf {{block(Component)}} composed of a mechanical structure that + transforms rotary motion into linear motion. + + + + + + + + + + leaf {{block(Component)}} composed of a mechanical structure that + transforms rotary motion into linear motion. + + + + + + + leaf {{block(Component)}} composed of a pump or other mechanism that + reduces volume and increases pressure of gases in order to condense the + gases to drive pneumatically powered pieces of equipment. + + + + + + + + + + leaf {{block(Component)}} composed of a pump or other mechanism that + reduces volume and increases pressure of gases in order to condense the + gases to drive pneumatically powered pieces of equipment. + + + + + + + leaf {{block(Component)}} composed of an inclined channel that conveys + material. + + + + + + + + + + leaf {{block(Component)}} composed of an inclined channel that conveys + material. + + + + + + + leaf {{block(Component)}} that turns on or off an electric current or + makes or breaks a circuit. + + + + + + + + + + leaf {{block(Component)}} that turns on or off an electric current or + makes or breaks a circuit. + + + + + + + leaf {{block(Component)}} that provides or applies a stretch or strain + to another mechanism. + + + + + + + + + + leaf {{block(Component)}} that provides or applies a stretch or strain + to another mechanism. + + + + + + + leaf {{block(Component)}} composed of $$H_2 O$$. + + + + + + + + + + leaf {{block(Component)}} composed of $$H_2 O$$. + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + leaf {{block(Component)}} that provides a signal or measured value. + + + + + + + + + + leaf {{block(Component)}} that provides a signal or measured value. + + + + + + + leaf {{block(Component)}} composed of a heat exchange system that uses a + fluid to transfer heat to the atmosphere. + + + + + + + + + + leaf {{block(Component)}} composed of a heat exchange system that uses a + fluid to transfer heat to the atmosphere. + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that has + to be removed from a {{block(ToolMagazine)}} or {{block(Turret)}} to a + location outside of the piece of equipment. + + + + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that has + to be removed from a {{block(ToolMagazine)}} or {{block(Turret)}} to a + location outside of the piece of equipment. + + + + + + + leaf {{block(Component)}} that holds a part, stock material, or any + other item in place. + + + + + + + + + + leaf {{block(Component)}} that holds a part, stock material, or any + other item in place. + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is + awaiting transfer to a {{block(ToolMagazine)}} or {{block(Turret)}} from + outside of the piece of equipment. + + + + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is + awaiting transfer to a {{block(ToolMagazine)}} or {{block(Turret)}} from + outside of the piece of equipment. + + + + + + + leaf {{block(Component)}} that slows or stops a moving object by the + absorption or transfer of the energy of momentum, usually by means of + friction, electrical force, or magnetic force. + + + + + + + + + + leaf {{block(Component)}} that slows or stops a moving object by the + absorption or transfer of the energy of momentum, usually by means of + friction, electrical force, or magnetic force. + + + + + + + leaf {{block(Component)}} composed of a storage or mounting location for + a tool associated with a {{block(Turret)}}, {{block(GangToolBar)}}, or + {{block(ToolRack)}}. + + + + + + + + + + leaf {{block(Component)}} composed of a storage or mounting location for + a tool associated with a {{block(Turret)}}, {{block(GangToolBar)}}, or + {{block(ToolRack)}}. + + + + + + + leaf {{block(Component)}} composed of a chamber or bin in which + materials are stored temporarily, typically being filled through the top + and dispensed through the bottom. + + + + + + + + + + leaf {{block(Component)}} composed of a chamber or bin in which + materials are stored temporarily, typically being filled through the top + and dispensed through the bottom. + + + + + + + leaf {{block(Component)}} composed of an endless flexible band that + transmits motion for a piece of equipment or conveys materials and + objects. + + + + + + + + + + leaf {{block(Component)}} composed of an endless flexible band that + transmits motion for a piece of equipment or conveys materials and + objects. + + + + + + + leaf {{block(Component)}} that physically moves a tool from one location + to another. + + + + + + + + + + leaf {{block(Component)}} that physically moves a tool from one location + to another. + + + + + + + leaf {{block(Component)}} composed of a rotary storage unit for + material. + + + + + + + + + + leaf {{block(Component)}} composed of a rotary storage unit for + material. + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that has + been removed from {{term(spindle)}} or {{block(Turret)}} and awaiting + for return to a {{block(ToolMagazine)}}. + + + + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that has + been removed from {{term(spindle)}} or {{block(Turret)}} and awaiting + for return to a {{block(ToolMagazine)}}. + + + + + + + leaf {{block(Component)}} composed of interconnected series of objects + that band together and are used to transmit motion for a piece of + equipment or to convey materials and objects. + + + + + + + + + + leaf {{block(Component)}} composed of interconnected series of objects + that band together and are used to transmit motion for a piece of + equipment or to convey materials and objects. + + + + + + + leaf {{block(Component)}} composed of an electronic component or circuit + that amplifies power, electric current, or voltage. + + + + + + + + + + leaf {{block(Component)}} composed of an electronic component or circuit + that amplifies power, electric current, or voltage. + + + + + + + leaf {{block(Component)}} generally composed of an open container. + + + + + + + + + + leaf {{block(Component)}} generally composed of an open container. + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is no + longer usable for removal from a {{block(ToolMagazine)}} or + {{block(Turret)}}. + + + + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is no + longer usable for removal from a {{block(ToolMagazine)}} or + {{block(Turret)}}. + + + + + + + leaf {{block(Component)}} composed of a viscous liquid. + + + + + + + + + + leaf {{block(Component)}} composed of a viscous liquid. + + + + + + + leaf {{block(Component)}} composed of a surface for holding an object or + material. + + + + + + + + + + leaf {{block(Component)}} composed of a surface for holding an object or + material. + + + + + + + leaf {{block(Component)}} that breaks material into smaller pieces. + + + + + + + + + + leaf {{block(Component)}} that breaks material into smaller pieces. + + + + + + + leaf {{block(Component)}} that halts or controls the flow of a liquid, + gas, or other material through a passage, pipe, inlet, or outlet. + + + + + + + + + + leaf {{block(Component)}} that halts or controls the flow of a liquid, + gas, or other material through a passage, pipe, inlet, or outlet. + + + + + + + leaf {{block(Component)}} composed of a tool storage location associated + with a {{block(ToolMagazine)}} or {{block(AutomaticToolChanger)}}. + + + + + + + + + + leaf {{block(Component)}} composed of a tool storage location associated + with a {{block(ToolMagazine)}} or {{block(AutomaticToolChanger)}}. + + + + + + + leaf {{block(Component)}} that transforms electric energy from a source + to a secondary circuit. + + + + + + + + + + leaf {{block(Component)}} that transforms electric energy from a source + to a secondary circuit. + + + + + + + leaf {{block(Component)}} that emits a type of radiation. + + + + + + + + + + leaf {{block(Component)}} that emits a type of radiation. + + + + + + + leaf {{block(Component)}} generally composed of an enclosed container. + + + + + + + + + + leaf {{block(Component)}} generally composed of an enclosed container. + + + + + + + leaf {{block(Component)}} that measures position. + + + + + + + + + + leaf {{block(Component)}} that measures position. + + + + + + + leaf {{block(Component)}} composed of one or more cells in which + chemical energy is converted into electricity and used as a source of + power. + + + + + + + + + + leaf {{block(Component)}} composed of one or more cells in which + chemical energy is converted into electricity and used as a source of + power. + + + + + + + leaf {{block(Component)}} that interrupts an electric circuit. + + + + + + + + + + leaf {{block(Component)}} that interrupts an electric circuit. + + + + + + + leaf {{block(Component)}} that converts electrical, pneumatic, or + hydraulic energy into mechanical energy. + + + + + + + + + + leaf {{block(Component)}} that converts electrical, pneumatic, or + hydraulic energy into mechanical energy. + + + + + + + leaf {{block(Component)}} that dispenses liquid or powered materials. + + + + + + + + + + leaf {{block(Component)}} that dispenses liquid or powered materials. + + + + + + + leaf {{block(Component)}} composed of an electromechanical actuator that + produces deflection of a beam of light or energy in response to electric + current through its coil in a magnetic field. + + + + + + + + + + leaf {{block(Component)}} composed of an electromechanical actuator that + produces deflection of a beam of light or energy in response to electric + current through its coil in a magnetic field. + + + + + + + leaf {{block(Component)}} that raises, drives, exhausts, or compresses + fluids or gases by means of a piston, plunger, or set of rotating vanes. + + + + + + + + + + leaf {{block(Component)}} that raises, drives, exhausts, or compresses + fluids or gases by means of a piston, plunger, or set of rotating vanes. + + + + + + + leaf {{block(Component)}} that strengthens, support, or fastens objects + in place. + + + + + + + + + + leaf {{block(Component)}} that strengthens, support, or fastens objects + in place. + + + + + + + leaf {{block(Component)}} that measures linear motion or position. + **DEPRECATION WARNING** : May be deprecated in the future. Recommend + using {{block(Encoder)}}. + + + + + + + + + + leaf {{block(Component)}} that measures linear motion or position. + **DEPRECATION WARNING** : May be deprecated in the future. Recommend + using {{block(Encoder)}}. + + + + + + + leaf {{block(Component)}} composed of an object or material on which a + form of work is performed. + + + + + + + + + + leaf {{block(Component)}} composed of an object or material on which a + form of work is performed. + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(Component)}} that provides information related to an individual + {{term(feature)}}. + + + + + + + + + + {{block(Component)}} that provides information related to an individual + {{term(feature)}}. + + + + + + + system that circulates air or regulates airflow without altering + temperature or humidity. + + + + + + + + + + system that circulates air or regulates airflow without altering + temperature or humidity. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Structure)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Structure)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Interface)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Interface)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Auxiliary)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Auxiliary)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(System)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(System)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Adapter)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Adapter)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Resource)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Resource)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Component + Types::Axis)}} types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Component + Types::Axis)}} types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Process)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Process)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Part)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Part)}} + types. + + + + + + + {{block(Resources)}} that {{termplural(organize)}} {{block(Material)}} + types. + + + + + + + + + + {{block(Resources)}} that {{termplural(organize)}} {{block(Material)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Controller)}} + entities. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Controller)}} + entities. + + + + + + + Compositions Model + + + + + + + Description + + + + + + + + + Extended tyoe for The vocab for the type of composition + + + + + + + + + + The vocab for the type of composition + + + + + + + {{block(Composition)}} composed of a mechanism that moves or + controls a mechanical part of a piece of equipment. It takes energy + usually provided by air, electric current, or liquid and converts + the energy into some kind of motion. + + + + + + + {{block(Composition)}} composed of an electronic component or + circuit that amplifies power, electric current, or voltage. + + + + + + + {{block(Composition)}} composed of a mechanical structure that + transforms rotary motion into linear motion. + + + + + + + {{block(Composition)}} composed of an endless flexible band that + transmits motion for a piece of equipment or conveys materials and + objects. + + + + + + + {{block(Composition)}} composed of a mechanism that slows down or + stops a moving object by the absorption or transfer of the energy of + momentum, usually by means of friction, electrical force, or + magnetic force. + + + + + + + {{block(Composition)}} composed of an interconnected series of + objects that band together and transmit motion for a piece of + equipment or to convey materials and objects. + + + + + + + {{block(Composition)}} composed of a mechanism that breaks material + into smaller pieces. + + + + + + + {{block(Composition)}} composed of a mechanism that holds a part, + stock material, or any other item in place. + + + + + + + {{block(Composition)}} composed of an inclined channel that conveys + material. + + + + + + + {{block(Composition)}} composed of a mechanism that interrupts an + electric circuit. + + + + + + + {{block(Composition)}} composed of a mechanism that strengthens, + supports, or fastens objects in place. + + + + + + + {{block(Composition)}} composed of a pump or other mechanism that + reduces volume and increases pressure of gases in order to condense + the gases to drive pneumatically powered pieces of equipment. + + + + + + + {{block(Composition)}} composed of a mechanical mechanism or closure + that covers a physical access portal into a piece of equipment + allowing or restricting access to other parts of the equipment. + + + + + + + {{block(Composition)}} composed of a mechanism that allows material + to flow for the purpose of drainage from, for example, a vessel or + tank. + + + + + + + {{block(Composition)}} composed of a mechanism that measures rotary + position. + + + + + + + {{block(Composition)}} composed of a mechanism that emits a type of + radiation. + + + + + + + {{block(Composition)}} composed of a mechanism that dispenses liquid + or powered materials. + + + + + + + {{block(Composition)}} composed of a mechanism that produces a + current of air. + + + + + + + {{block(Composition)}} composed of a substance or structure that + allows liquids or gases to pass through to remove suspended + impurities or to recover solids. + + + + + + + {{block(Composition)}} composed of an electromechanical actuator + that produces deflection of a beam of light or energy in response to + electric current through its coil in a magnetic field. + + + + + + + {{block(Composition)}} composed of a mechanism that holds a part, + stock material, or any other item in place. + + + + + + + {{block(Composition)}} composed of a chamber or bin that stores + materials temporarily, typically being filled through the top and + dispensed through the bottom. + + + + + + + {{block(Composition)}} composed of a mechanism that measures linear + motion or position. + + + + + + + {{block(Composition)}} composed of a mechanism that converts + electrical, pneumatic, or hydraulic energy into mechanical energy. + + + + + + + {{block(Composition)}} composed of a viscous liquid. + + + + + + + {{block(Composition)}} composed of a unit that provides power to + electric mechanisms. + + + + + + + {{block(Composition)}} composed of a mechanism or wheel that turns + in a frame or block and serves to change the direction of or to + transmit force. + + + + + + + {{block(Composition)}} composed of an apparatus that raises, drives, + exhausts, or compresses fluids or gases by means of a piston, + plunger, or set of rotating vanes. + + + + + + + {{block(Composition)}} composed of a rotary storage unit for + material. + + + + + + + {{block(Composition)}} composed of a mechanism that provides a + signal or measured value. + + + + + + + {{block(Composition)}} composed of a mechanism that flattens or + spreads materials. + + + + + + + {{block(Composition)}} composed of one or more cells that converts + chemical energy to electricity and serves as a source of power. + + + + + + + {{block(Composition)}} composed of a mechanism that turns on or off + an electric current or makes or breaks a circuit. + + + + + + + {{block(Composition)}} composed of a surface that holds an object or + material. + + + + + + + {{block(Composition)}} composed of a receptacle or container that + holds material. + + + + + + + {{block(Composition)}} composed of a mechanism that provides or + applies a stretch or strain to another mechanism. + + + + + + + {{block(Composition)}} composed of a mechanism that transforms + electric energy from a source to a secondary circuit. + + + + + + + {{block(Composition)}} composed of a mechanism that halts or + controls the flow of a liquid, gas, or other material through a + passage, pipe, inlet, or outlet. + + + + + + + {{block(Composition)}} composed of a container for liquid or + powdered materials. + + + + + + + {{block(Composition)}} composed of a fluid. + + + + + + + {{block(Composition)}} composed of a string like piece or filament + of relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + {{block(Composition)}} composed of an object or material on which a + form of work is performed. + + + + + + + {{block(Composition)}} composed of a heat exchange system that uses + a fluid to transfer heat to the atmosphere. + + + + + + + {{block(Composition)}} composed of a tool storage location + associated with a {{block(ToolMagazine)}} or + {{block(AutomaticToolChanger)}}. + + + + + + + {{block(Composition)}} composed of a storage or mounting location + for a tool associated with a {{block(Turret)}}, + {{block(GangToolBar)}}, or {{block(ToolRack)}}. + + + + + + + {{block(Composition)}} composed of a mechanism that physically moves + a tool from one location to another. + + + + + + + {{block(Pot)}} for a tool awaiting transfer from a + {{block(ToolMagazine)}} to {{term(spindle)}} or {{block(Turret)}}. + + + + + + + {{block(Pot)}} for a tool removed from {{term(spindle)}} or + {{block(Turret)}} and awaiting for return to a + {{block(ToolMagazine)}}. + + + + + + + {{block(Pot)}} for a tool awaiting transfer to a + {{block(ToolMagazine)}} or {{block(Turret)}} from outside of the + piece of equipment. + + + + + + + {{block(Pot)}} for a tool to be removed from a + {{block(ToolMagazine)}} or {{block(Turret)}} to a location outside + of the piece of equipment. + + + + + + + {{block(Pot)}} for a tool that is no longer usable for removal from + a {{block(ToolMagazine)}} or {{block(Turret)}}. + + + + + + + + + The vocab for the type of composition + + + + + + + + Description + + + + + + + See {{sect(Description)}}. + + + + + + + technical information about an entity describing its physical + layout, functional characteristics, and relationships with other + entities. + + + + + + + + unique identifier for the power source. + + + + + + + The composition's universally unique id. + + + + + + + identifier of the maintenance activity. + + + + + + + The type of composition + + + + + + + + A reference to an identifier + + + + + + + + References Model + + + + + + + + + + Description + + + + + + A reference to an id in the MTConnectDevices model + + + + + + + identifier of the maintenance activity. + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + data type of Entry value + + + + + + + + Abstract configuration + + + + + + + Abstract configuration + + + + + + + The configuration data associated with this component. + + + + + + + + + + An entry for a configuration element with three dimensional values + + + + + + + + the key + + + + + + + + + + A Configuration element with three dimensional value for 'X Y + Z' + + + + + + + Constraints for Entry Values + + + + + + + + + A Configuration element with three dimensional value for 'A B + C' + + + + + + + Constraints for Entry Values + + + + + + + + + The time the calibration was preformed + + + + + + + + The time the next calibration should be preformed + + + + + + + + The initials of the person doing the calibration + + + + + + + + The firmware version of this sensor + + + + + + + + The channel number + + + + + + + + See {{block(SensorConfiguration)}}. + + + + + + + + + Version number for the sensor unit as specified by the + manufacturer. + + + + + + + Date upon which the {{term(sensor unit)}} was last calibrated to + the {{term(sensor element)}}. + + + + + + + Date upon which the {{term(sensor element)}} is next scheduled + to be calibrated with the {{term(sensor unit)}}. + + + + + + + The initials of the person verifying the validity of the + calibration data. + + + + + + + Any additional properties + + + + + + + {{block(Channels)}} groups one or more {{block(Channel)}} + entities. See {{block(Channel)}}. + + + + + + + + + + + See {{block(SensorConfiguration)}}. + + + + + + + {{block(Channels)}} groups one or more {{block(Channel)}} entities. See + {{block(Channel)}}. + + + + + + + Description + + + + + + + + + Description + + + + + + + See {{sect(Description)}}. + + + + + + + Date upon which the {{term(sensor unit)}} was last calibrated to the + {{term(sensor element)}}. + + + + + + + Date upon which the {{term(sensor element)}} is next scheduled to be + calibrated with the {{term(sensor unit)}}. + + + + + + + The initials of the person verifying the validity of the calibration + data. + + + + + + + + The channel id + + + + + + + identifier of the maintenance activity. + + + + + + + + The peak value + + + + + + + + {{block(Specifications)}} groups one or more {{block(Specification)}} + entities. See {{package(Specifications)}}. + + + + + + + + + + + + + + {{block(Specifications)}} groups one or more {{block(Specification)}} + entities. See {{package(Specifications)}}. + + + + + + + Extended tyoe for A reference to the creator of the Specification + + + + + + + + + + A reference to the creator of the Specification + + + + + + + The manufacturer of a piece of equipment or component. + + + + + + + The owner or implementer of a piece of equipment or component. + + + + + + + + + A reference to the creator of the Specification + + + + + + + + A specification + + + + + + The identity of the Specificaiton + + + + + + + The type of measurement + + + + + + + A reference to the creator of the Specification + + + + + + + The type of measurement + + + + + + + identifier of the maintenance activity. + + + + + + + The optional data item identifier + + + + + + + The optional composition identifier + + + + + + + The optional coordinate system identifier + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + + A specification + + + + + + + design characteristics for a piece of equipment. + + + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + upper conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + upper boundary indicating increased concern and supervision may + be required. + + + + + + + lower boundary indicating increased concern and supervision may + be required. + + + + + + + lower conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + + + + + design characteristics for a piece of equipment. + + + + + + + The limit of a constraint + + + + + + + + + + The limit of a constraint + + + + + + + numeric upper constraint. + + + + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + + + + numeric target or expected value. + + + + + + + upper conformance boundary for a variable. > Note: immediate concern + or action may be required. + + + + + + + + + + upper conformance boundary for a variable. > Note: immediate concern + or action may be required. + + + + + + + upper boundary indicating increased concern and supervision may be + required. + + + + + + + + + + upper boundary indicating increased concern and supervision may be + required. + + + + + + + lower boundary indicating increased concern and supervision may be + required. + + + + + + + + + + lower boundary indicating increased concern and supervision may be + required. + + + + + + + lower conformance boundary for a variable. > Note: immediate concern + or action may be required. + + + + + + + + + + lower conformance boundary for a variable. > Note: immediate concern + or action may be required. + + + + + + + {{block(Specification)}} that provides information used to assess the + conformance of a variable to process requirements. + + + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + + + + + {{block(Specification)}} that provides information used to assess the + conformance of a variable to process requirements. + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + upper conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + upper boundary indicating increased concern and supervision may be + required. + + + + + + + numeric target or expected value. + + + + + + + lower boundary indicating increased concern and supervision may be + required. + + + + + + + lower conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + upper conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + upper boundary indicating increased concern and supervision may be + required. + + + + + + + lower boundary indicating increased concern and supervision may be + required. + + + + + + + lower conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + upper conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + numeric target or expected value. + + + + + + + lower conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + + + {{block(Relationships)}} groups one or more + {{block(ConfigurationRelationship)}} types. See + {{package(Relationships)}}. + + + + + + + + + + + + + + {{block(Relationships)}} groups one or more + {{block(ConfigurationRelationship)}} types. See + {{package(Relationships)}}. + + + + + + + The list of possible association types + + + + + + + The related entity is a parent + + + + + + + The related entity is a child + + + + + + + The related entity is a peer + + + + + + + + + device relationships + + + + + + + a system + + + + + + + an auxiliary + + + + + + + + + The criticality + + + + + + + critical + + + + + + + Not critical + + + + + + + + + A relationship between this component and something else + + + + + + The relationship identifier + + + + + + + identifier of the maintenance activity. + + + + + + + The assciation type + + + + + + + Criticality + + + + + + + + A relationship between this component and something else + + + + + + + {{block(ConfigurationRelationship)}} that describes the association + between two components within a piece of equipment that function + independently but together perform a capability or service within a + piece of equipment. + + + + + + + + A reference to the device uuid + + + + + + + + + + {{block(ConfigurationRelationship)}} that describes the association + between two components within a piece of equipment that function + independently but together perform a capability or service within a + piece of equipment. + + + + + + + {{block(ConfigurationRelationship)}} that describes the association + between two pieces of equipment that function independently but together + perform a manufacturing operation. + + + + + + + + A reference to the device uuid + + + + + + + The type of relatiship + + + + + + + {{term(URL)}} giving the location of the image file. + + + + + + + Description + + + + + + + + + + {{block(ConfigurationRelationship)}} that describes the association + between two pieces of equipment that function independently but together + perform a manufacturing operation. + + + + + + + The type of coordinate system + + + + + + + The world + + + + + + + The base of the manipulator chain + + + + + + + The object + + + + + + + The current task + + + + + + + The last joint in the chain + + + + + + + The tool's coord + + + + + + + The platform + + + + + + + For machine tools, the coordinate system in the work area + + + + + + + For machine tools, the coordinate system in the work area + + + + + + + + + {{block(CoordinateSystems)}} groups one or more + {{block(CoordinateSystem)}} entities. See + {{package(CoordinateSystems)}}. + + + + + + + + + Description + + + + + + + + + + + {{block(CoordinateSystems)}} groups one or more + {{block(CoordinateSystem)}} entities. See + {{package(CoordinateSystems)}}. + + + + + + + Description + + + + + + + See {{sect(Origin)}}. + + + + + + + The location (no parent) as DataSet + + + + + + + See {{sect(Transformation)}}. + + + + + + + + The coordinate system identifier + + + + + + + identifier of the maintenance activity. + + + + + + + The optional name of the coordinate system + + + + + + + The parent of the coordinate system + + + + + + + The coordinate system type + + + + + + + uuid + + + + + + + + See {{sect(Origin)}}. + + + + + + + + + + See {{sect(Transformation)}}. + + + + + + + + translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + An offset applied first + + + + + + + + + rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + A quaternion transform applied second + + + + + + + + + + The types of motion + + + + + + + Rotates around an axis with a fixed range of motion + + + + + + + Revolves around an axis with a continuous range of motion + + + + + + + Sliding linear motion along an axis with a fixed range of motion + + + + + + + The axis does not move. + + + + + + + + + The actuation of this component + + + + + + + The movement is initiated by the component. + + + + + + + The motion is computed and is used for expressing an imaginary + movement. + + + + + + + There is no actuation of this Axis. + + + + + + + + + The unit vector along which the motion occurs + + + + + + + + + + The description of the motion + + + + + + + Any elements + + + + + + + + + See {{sect(Motion)}}. + + + + + + + + + See {{sect(Description)}}. + + + + + + + + The location (no parent) + + + + + + + See {{sect(Origin)}}. + + + + + + + See {{sect(Transformation)}}. + + + + + + + + + The axis motion + + + + + + + See {{sect(Axis)}}. + + + + + + + + + The coordinate system identifier + + + + + + + The parent of the coordinate system + + + + + + + The identifier of the coordinate system that this motion is + relative to + + + + + + + The motion type + + + + + + + The actuation method + + + + + + + + + + See {{sect(Motion)}}. + + + + + + + A reference to another model + + + + + + + + A reference to an item in a model + + + + + + + + A three dimensional value 'X Y Z' or 'A B C' + + + + + + + + + + + The unit vector to scale the model + + + + + + + + + + See {{sect(SolidModel)}}. + + + + + + + + + See {{sect(Transformation)}}. + + + + + + + + See {{sect(Scale)}}. + + + + + + + Scaling vector for the model + + + + + + + + + the unique identifier for this entity within the MTConnectDevices + document + + + + + + + The associated model file if an item reference is used + + + + + + + {{term(URL)}} giving the location of the image file. + + + + + + + Description + + + + + + + The reference to the item within the model within the related + geometry. A modelIdRef MUST be given. + + + + + + + The format of the referenced document + + + + + + + The identifier of the coordinate system that this motion is + relative to + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + The units as expressed by the machine + + + + + + + + + + See {{sect(SolidModel)}}. + + + + + + + Extended tyoe for Solid model media types + + + + + + + + + + Solid model media types + + + + + + + ISO 10303 STEP AP203 or AP242 format + + + + + + + Stereolithography file format + + + + + + + Geometry Description Markup Language + + + + + + + Wavefront OBJ file format + + + + + + + ISO 17506 + + + + + + + Initial Graphics Exchange Specification + + + + + + + Autodesk file format + + + + + + + Dassault file format + + + + + + + Parasolid XT Siemens data interchange format + + + + + + + + + Solid model media types + + + + + + + + url of an image file + + + + + + + + mime type + + + + + + + + This section provides semantic information for the {{block(ImageFile)}} + entity. + + + + + + + + + reference to a file containing an image of the + {{block(Component)}}. + + + + + + + + + + + This section provides semantic information for the {{block(ImageFile)}} + entity. + + + + + + + reference to a file containing an image of the {{block(Component)}}. + + + + + + + + identifier + + + + + + + identifier of the maintenance activity. + + + + + + + URL of image file + + + + + + + mime type of image file + + + + + + + + + + The item's reference to the component + + + + + + + + The name of the power source + + + + + + + + The order of precedence for a given power source + + + + + + + + The type of power source + + + + + + + main or principle + + + + + + + alternate or not primary + + + + + + + held near at hand and ready for use and is uninterruptible + + + + + + + + + This section provides semantic information for the + {{block(PowerSource)}} entity. ![PowerSources](figures/PowerSources.png + "PowerSources"){: width="0.8"} + + + + + + + + + potential energy sources for the {{block(Component)}}. + + + + + + + + + + + This section provides semantic information for the + {{block(PowerSource)}} entity. ![PowerSources](figures/PowerSources.png + "PowerSources"){: width="0.8"} + + + + + + + potential energy sources for the {{block(Component)}}. + + + + + + + optional precedence for a given power source + + + + + + + single data value that is expected to be reported for a + {{block(DataItem)}}. {{property(Constraints::Value)}} **MUST NOT** + be used in conjunction with any other {{block(Constraint)}} + elements. + + + + + + + + type of power source + + + + + + + identifier + + + + + + + reference to component + + + + + + + + The interval between adjacent sampleing of data + + + + + + + + The frequency a measurement is sampled + + + + + + + + The constrained value for this data item + + + + + + + + The constrained value for this data item + + + + + + + + The constrained value for this data item + + + + + + + + An idref to the component id + + + + + + + + An idref to the data item id + + + + + + + + The item's reference to the data item or specificatiton + + + + + + + + The name of a related component + + + + + + + + The id reference for the coordinate system associated with this data + item + + + + + + + + An discrete event + + + + + + + + The description of a data item, can be free form text or elements + + + + + + + Any elements + + + + + + + + + The minimum limit on the change in a value + + + + + + + + The measurement sampling type + + + + + + + An event represents a change in state occurs at a point in time. + Note: An event does not occur at predefined frequencies. + + + + + + + A sample is a data point for continuous data items, that is, the + value of a data item at a point in time. + + + + + + + The condition of the device + + + + + + + + + The multiplier for the native value. Conversion divides by this value + + + + + + + + Description + + + + + + + series of sampled data. The data is reported for a specified number + of samples and each sample is reported with a fixed period. + + + + + + + measured value of the sample data. If no + {{property(DataItem::representation)}} is specified for a data item, + the {{property(DataItem::representation)}} **MUST** be determined to + be `VALUE`. + + + + + + + reported value(s) are represented as a set of {{termplural(key-value + pair)}}. Each reported value in the {{term(data set)}} **MUST** have + a unique key. + + + + + + + **DEPRECATED** as {{property(DataItem::representation)}} type in + *MTConnect Version 1.5*. Replaced by the + {{property(DataItem::discrete)}}. + + + + + + + two dimensional set of {{termplural(key-value pair)}} where the + {{block(Entry)}} represents a row, and the value is a set of + {{term(key-value pair)}} {{block(Cell)}} elements. A {{term(table)}} + follows the same behavior as the {{term(data set)}} for change + tracking, clearing, and history. When an {{block(Entry)}} changes, + all {{block(Cell)}} elements update as a single unit following the + behavior of a {{term(data set)}}. > Note: It is best to use + {{block(Variable)}} if the {{block(Cell)}} entities represent + multiple semantic types. Each {{block(Entry)}} in the + {{term(table)}} **MUST** have a unique key. Each {{block(Cell)}} of + each {{block(Entry)}} in the {{term(table)}} **MUST** have a unique + key. See {{block(Representation)}} in {{package(Observation + Information Model)}}, for a description of {{block(Entry)}} and + {{block(Cell)}} elements. + + + + + + + + + The type of filter + + + + + + + new value **MUST NOT** be reported for a data item unless the + measured value has changed from the last reported value by at least + the delta given as the value of this element. The value of + {{block(Filter)}} **MUST** be an absolute value using the same units + as the reported data. + + + + + + + data reported for a data item is provided on a periodic basis. The + `PERIOD` for reporting data is defined in the value of the + {{block(Filter)}}. The value of {{block(Filter)}} **MUST** be an + absolute value reported in seconds representing the time between + reported samples of the value of the data item. + + + + + + + + + + + + + + information reported about a piece of equipment. + + + + + + + + + information reported about a piece of equipment. + + + + + + + identifies the {{block(Component)}}, {{block(DataItem)}}, or + {{block(Composition)}} from which a measured value originates. + + + + + + + {{termplural(organize)}} a set of expected values that can be + reported for a {{block(DataItem)}}. + + + + + + + {{block(Filters)}} groups one or more {{block(Filter)}} entities + associated with the {{block(DataItem)}}. + + + + + + + starting value for a {{block(DataItem)}} as well as the value to be + set for the {{block(DataItem)}} after a reset event. + + + + + + + type of event that may cause a reset to occur. + + + + + + + defines the meaning of {{block(Entry)}} and {{block(Cell)}} entities + when the associated {{property(DataItem::representation)}} is either + `DATA_SET` or `TABLE`. + + + + + + + {{block(Relationships)}} groups one or more + {{block(ConfigurationRelationship)}} types. See + {{package(Relationships)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + unique identifier for the power source. + + + + + + + The type of measurement + + + + + + + The sub type for the measurement + + + + + + + The statistical operation on this data + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + The units as expressed by the machine + + + + + + + The units as expressed by the machine + + + + + + + The category of the data item + + + + + + + Description + + + + + + + The coordinate system reference to a particular coordinate system + + + + + + + The optional composition identifier + + + + + + + Used as the default sample rate for waveforms + + + + + + + Description + + + + + + + The number of significant digits for this data item + + + + + + + Description + + + + + + + + A set of limits for a data item + + + + + + + + + single data value that is expected to be reported for a + {{block(DataItem)}}. {{property(Constraints::Value)}} **MUST + NOT** be used in conjunction with any other + {{block(Constraint)}} elements. + + + + + + + + + numeric lower constraint. + + + + + + + numeric upper constraint. + + + + + + + numeric target or expected value. + + + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + + + {{block(Filters)}} groups one or more {{block(Filter)}} entities + associated with the {{block(DataItem)}}. + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + + + A starting point for a data item + + + + + + + + + + The value element + + + + + + + + + + The filter for the data item + + + + + + + + The type of filter, ABSOLUTE or PERCENT + + + + + + + + + + A native data source + + + + + + + + The optional data item within the source component that provides + the underlying data + + + + + + + The component that is collecting the data associated with this + data item + + + + + + + The optional composition identifier for the source of this data + item + + + + + + + + + + The DataItem Definition + + + + + + + See {{sect(Description)}}. + + + + + + + {{block(EntryDefinitions)}} groups one or more + {{block(EntryDefinition)}} entities. See {{sect(EntryDefinition)}}. + + + + + + + {{block(CellDefinitions)}} groups one or more + {{block(CellDefinition)}} entities. See {{sect(CellDefinition)}}. + + + + + + + + + {{block(EntryDefinitions)}} groups one or more + {{block(EntryDefinition)}} entities. See {{sect(EntryDefinition)}}. + + + + + + + semantic definition of an {{block(Entry)}}. + + + + + + + + + + unique key + + + + + + + The type of measurement + + + + + + + The type of measurement + + + + + + + The sub type for the measurement + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + + semantic definition of an {{block(Entry)}}. + + + + + + + See {{sect(Description)}}. + + + + + + + {{block(CellDefinitions)}} groups one or more + {{block(CellDefinition)}} entities. See {{sect(CellDefinition)}}. + + + + + + + + + + {{block(CellDefinitions)}} groups one or more {{block(CellDefinition)}} + entities. See {{sect(CellDefinition)}}. + + + + + + + semantic definition of a {{block(Cell)}}. + + + + + + + + + semantic definition of a {{block(Cell)}}. + + + + + + + See {{sect(Description)}}. + + + + + + + + + + Organizes DataItemRelationship and SpecificationRelationship + + + + + + + + + + Description + + + + + + identifier of the maintenance activity. + + + + + + + A reference to the related DataItem id. + + + + + + + + Description + + + + + + + How the data items are related + + + + + + + A reference to a DataItem that associates the values with an + external entity + + + + + + + The referenced DataItem provides the id of the effective Coordinate + System + + + + + + + The referenced DataItem provides process limits. + + + + + + + The referenced DataItem provides the observed values. + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(DataItem)}} described by + {{property(DataItemRelationship::type)}}. + + + + + + + + type of the power source. + + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(DataItem)}} described by + {{property(DataItemRelationship::type)}}. + + + + + + + How the data items are related + + + + + + + The referenced DataItem provides process limits. + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(Specification)}} described by + {{property(SpecificationRelationship::type)}} and + {{property(SpecificationRelationship::idRef)}}. + + + + + + + + type of the power source. + + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(Specification)}} described by + {{property(SpecificationRelationship::type)}} and + {{property(SpecificationRelationship::idRef)}}. + + + + \ No newline at end of file diff --git a/schemas/MTConnectDevices_2.5_1.0.xsd b/schemas/MTConnectDevices_2.5_1.0.xsd new file mode 100644 index 000000000..a2321cc7e --- /dev/null +++ b/schemas/MTConnectDevices_2.5_1.0.xsd @@ -0,0 +1,10430 @@ + + + + + + + + root entity of an {{term(MTConnectDevices Response Document)}} that + contains the {{term(Device Information Model)}} of one or more + {{block(Device)}} entities. + ![MTConnectDevices](figures/MTConnectDevices.png + "MTConnectDevices"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectDevices)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + The sender of the message + + + + + + + + The date and time the document was created + + + + + + + + A sequence number + + + + + + + + + + + A debugging flag for testing. + + + + + + + + The instance number of the agent, used for fault tolerance + + + + + + + + + + + The size of the agents buffer + + + + + + + + + + + The time the sample was reported + + + + + + + + The time a sample occurred + + + + + + + + A version number + + + + + + + + A short name for any element + + + + + + + + A universally unique id that uniquely identifies the element for + it's entire life + + + + + + + + A serial number for a piece of equipment + + + + + + + + The measurement source + + + + + + + + A sample rate in milliseconds per sample + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + + An identifier + + + + + + + + The number significant digits + + + + + + + + The item's reference to the Device model composition + + + + + + + + A length of time in seconds + + + + + + + + A flag indicating the item has been removed + + + + + + + + The key for adata set + + + + + + + + A timestamp in 8601 format of the last update of the Device information + for any device + + + + + + + + The unique id of the asset + + + + + + + + An asset type + + + + + + + + The maximum number of assets + + + + + + + + + + + The number of assets + + + + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + The limit of a value + + + + + + + + Common floating point sample value + + + + + + + + + + + + A three dimensional value 'X Y Z' or 'A B C' + + + + + + + + + + + A description + + + + + + + + Extended tyoe for The types of measurements available + + + + + + + + + + The types of measurements available + + + + + + + positive rate of change of velocity. + + + + + + + accumulated time for an activity or event. + + + + + + + strength of electrical current. **DEPRECATED** in *Version 1.6*. + Replaced by `AMPERAGE_AC` and `AMPERAGE_DC`. + + + + + + + angular position. + + + + + + + positive rate of change of angular velocity. + + + + + + + rate of change of angular position. + + + + + + + feedrate of a linear axis. + + + + + + + fluid capacity of an object or container. + + + + + + + geometric capacity of an object or container. + + + + + + + percentage of one component within a mixture of components. + + + + + + + ability of a material to conduct electricity. + + + + + + + speed difference (relative velocity) between the cutting mechanism + and the surface of the workpiece it is operating on. + + + + + + + volumetric mass of a material per unit volume of that material. + + + + + + + rate of change in spatial volume of material deposited in an + additive manufacturing process. + + + + + + + density of the material deposited in an additive manufacturing + process per unit of volume. + + + + + + + mass of the material deposited in an additive manufacturing process. + + + + + + + rate at which a spatial volume of material is deposited in an + additive manufacturing process. + + + + + + + spatial volume of material to be deposited in an additive + manufacturing process. + + + + + + + change in position of an object. + + + + + + + {{block(Wattage)}} used or generated by a component over an interval + of time. + + + + + + + amount of time a piece of equipment or a sub-part of a piece of + equipment has performed specific activities. + + + + + + + amount of a substance remaining compared to the planned maximum + amount of that substance. + + + + + + + rate of flow of a fluid. + + + + + + + number of occurrences of a repeating event per unit time. + + + + + + + position in three-dimensional space. **DEPRECATED** in Version 1.1. + + + + + + + length of an object. + + + + + + + level of a resource. **DEPRECATED** in *Version 1.2*. See + `FILL_LEVEL`. + + + + + + + {{term(force)}} applied to a mass in one direction only. + + + + + + + actual versus the standard rating of a piece of equipment. + + + + + + + mass of an object(s) or an amount of material. + + + + + + + feedrate for the axes, or a single axis, associated with a + {{block(Path)}} component. + + + + + + + feedrate for the axes, or a single axis. + + + + + + + position of a control point associated with a {{block(Controller)}} + or a {{block(Path)}}. + + + + + + + acidity or alkalinity of a solution. + + + + + + + point along an axis in a {{term(cartesian coordinate system)}}. + + + + + + + ratio of real power flowing to a load to the apparent power in that + AC circuit. + + + + + + + force per unit area measured relative to atmospheric pressure. + Commonly referred to as gauge pressure. + + + + + + + amount of time a piece of equipment has performed different types of + activities associated with the process being performed at that piece + of equipment. + + + + + + + degree to which a substance opposes the passage of an electric + current. + + + + + + + rotational speed of a rotary axis. + + + + + + + sound level or sound pressure level relative to atmospheric + pressure. + + + + + + + rotational speed of the rotary axis. **DEPRECATED** in *Version + 1.2*. Replaced by `ROTARY_VELOCITY`. + + + + + + + amount of deformation per unit length of an object when a load is + applied. + + + + + + + degree of hotness or coldness measured on a definite scale. + + + + + + + force that stretches or elongates an object. + + + + + + + angular displacement. + + + + + + + turning force exerted on an object or by an object. + + + + + + + rate of change of position of a {{block(Component)}}. + + + + + + + fluid's resistance to flow. + + + + + + + electrical potential between two points. **DEPRECATED** in *Version + 1.6*. Replaced by `VOLTAGE_AC` and `VOLTAGE_DC`. + + + + + + + apparent power in an electrical circuit, equal to the product of + root-mean-square (RMS) voltage and RMS current (commonly referred to + as VA). + + + + + + + reactive power in an AC electrical circuit (commonly referred to as + VAR). + + + + + + + fluid volume of an object or container. + + + + + + + geometric volume of an object or container. + + + + + + + power flowing through or dissipated by an electrical circuit or + piece of equipment. + + + + + + + electrical current that reverses direction at regular short + intervals. + + + + + + + electric current flowing in one direction only. + + + + + + + electrical potential between two points in an electrical circuit in + which the current periodically reverses direction. + + + + + + + electrical potential between two points in an electrical circuit in + which the current is unidirectional. + + + + + + + dimension of an entity relative to the X direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Y direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Z direction of the referenced + coordinate system. + + + + + + + dimension of a diameter. + + + + + + + angular position of a plane or vector relative to a {{term(cartesian + coordinate system)}} + + + + + + + amount of water vapor present expressed as a percent to reach + saturation at the same temperature. + + + + + + + amount of water vapor expressed in grams per cubic meter. + + + + + + + ratio of the water vapor present over the total weight of the water + vapor and air present expressed as a percent. + + + + + + + average rate of change of values for data items in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + average rate of change of values for assets in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + change of pressure per unit time. + + + + + + + negative rate of change of velocity. + + + + + + + negative rate of change of angular velocity. + + + + + + + force per unit area measured relative to a vacuum. + + + + + + + percentage open where 100% is fully open and 0% is fully closed. + + + + + + + temperature at which moisture begins to condense, corresponding to + saturation for a given absolute humidity. + + + + + + + force relative to earth's gravity. + + + + + + + acceleration relative to Earth's gravity of 9.80665 + `METER/SECOND^2`. + + + + + + + maximum rated charge a battery is capable of maintaining based on + the battery discharging at a specified current over a specified time + period. + + + + + + + value of current being drawn from the {{block(Component)}}. + + + + + + + value of the current being supplied to the {{block(Component)}} for + the purpose of charging. + + + + + + + value of the battery's present capacity expressed as a + percentage of the battery's maximum rated capacity. + + + + + + + difference between actual and commanded position at the end of a + motion. + + + + + + + difference between actual and commanded position at any specific + point in time during a motion. + + + + + + + difference between the commanded encoder/resolver position, and the + actual encoder/resolver position when motion is complete. + + + + + + + angular difference between the commanded encoder/resolver position, + and the actual encoder/resolver position when motion is complete. + + + + + + + difference between the commanded encoder/resolver position and the + actual encoder/resolver position at any specified point in time + during a motion. + + + + + + + angular difference between the commanded encoder/resolver position + and the actual encoder/resolver position at any specified point in + time during a motion. + + + + + + + absolute value of the change in position along a vector. + + + + + + + absolute value of the change in angular position around a vector + + + + + + + point in a {{term(cartesian coordinate system)}}. + + + + + + + set of axes currently associated with a {{block(Path)}} or + {{block(Controller)}}. + + + + + + + operational state of an apparatus for moving or controlling a + mechanism or system. + + + + + + + **DEPRECATED:** Replaced with `CONDITION` category data items in + Version 1.1.0. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been added or + changed. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been removed. + + + + + + + {{term(agent)}}'s ability to communicate with the data source. + + + + + + + describes the way the axes will be associated to each other. This is + used in conjunction with `COUPLED_AXES` to indicate the way they are + interacting. + + + + + + + value of a signal or calculation issued to adjust the feedrate of an + individual linear type axis. + + + + + + + state of the axis lockout function when power has been removed and + the axis is allowed to move freely. + + + + + + + state of a {{block(Linear)}} or {{block(Rotary)}} component + representing an axis. + + + + + + + line of code or command being executed by a {{block(Controller)}} + entity. + + + + + + + total count of the number of blocks of program code that have been + executed since execution started. + + + + + + + state of an interlock function or control logic state intended to + prevent the associated {{block(Chuck)}} component from being + operated. + + + + + + + operating state of a mechanism that holds a part or stock material + during a manufacturing process. It may also represent a mechanism + that holds any other mechanism in place within a piece of equipment. + + + + + + + programmatic code being executed. **DEPRECATED** in *Version 1.1*. + + + + + + + operating state of a mechanism represented by a + {{block(Composition)}} entity. + + + + + + + current mode of the {{block(Controller)}} component. + + + + + + + setting or operator selection that changes the behavior of a piece + of equipment. + + + + + + + set of associated axes. + + + + + + + time and date code associated with a material or other physical + item. + + + + + + + identifier of another piece of equipment that is temporarily + associated with a component of this piece of equipment to perform a + particular function. + + + + + + + direction of motion. + + + + + + + operational state of a {{block(Door)}} component or composition + element. + + + + + + + state of the emergency stop signal for a piece of equipment, + controller path, or any other component or subsystem of a piece of + equipment. + + + + + + + indication of whether the end of a piece of bar stock being feed by + a bar feeder has been reached. + + + + + + + indication that a piece of equipment, or a sub-part of a piece of + equipment, is performing specific types of activities. + + + + + + + operating state of a {{block(Component)}}. + + + + + + + current intended production status of the {{block(Component)}}. + + + + + + + hardness of a material. + + + + + + + current line of code being executed. **DEPRECATED** in *Version + 1.4.0*. + + + + + + + identifier for a {{block(Block)}} of code in a {{block(Program)}}. + + + + + + + position of a block of program code within a control program. + + + + + + + identifier of a material used or consumed in the manufacturing + process. + + + + + + + identifies the layers of material applied to a part or product as + part of an additive manufacturing process. + + + + + + + information to be transferred from a piece of equipment to a client + software application. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + identifier for a pallet. + + + + + + + aggregate count of parts. + + + + + + + indication designating whether a part or work piece has been + detected or is present. + + + + + + + identifier of a part in a manufacturing operation. + + + + + + + identifier of a part or product moving through the manufacturing + process. **DEPRECATED** in *Version 1.7*. `PART_NUMBER` is now a + `subType` of `PART_KIND_ID`. + + + + + + + value of a signal or calculation issued to adjust the feedrate for + the axes associated with a {{block(Path)}} component that may + represent a single axis or the coordinated movement of multiple + axes. + + + + + + + describes the operational relationship between a {{block(Path)}} + entity and another {{block(Path)}} entity for pieces of equipment + comprised of multiple logical groupings of controlled axes or other + logical operations. + + + + + + + indication of the status of the source of energy for an entity to + allow it to perform its intended function or the state of an + enabling signal providing permission for the entity to perform its + functions. + + + + + + + status of the {{block(Component)}}. **DEPRECATED** in *Version + 1.1.0*. + + + + + + + time and date associated with an activity or event. + + + + + + + name of the logic or motion program being executed by the + {{block(Controller)}} component. + + + + + + + comment or non-executable statement in the control program. + + + + + + + indication of the status of the {{block(Controller)}} components + program editing mode. A program may be edited while another is + executed. + + + + + + + name of the program being edited. This is used in conjunction with + {{block(ProgramEdit)}} when in `ACTIVE` state. + + + + + + + non-executable header section of the control program. + + + + + + + {{term(URI)}} for the source file associated with + {{block(Program)}}. + + + + + + + defines whether the logic or motion program defined by + {{block(Program)}} is being executed from the local memory of the + controller or from an outside source. + + + + + + + indication of the nesting level within a control program that is + associated with the code or instructions that is currently being + executed. + + + + + + + current operating mode for a {{block(Rotary)}} type axis. + + + + + + + percentage change to the velocity of the programmed velocity for a + {{block(Rotary)}} axis. + + + + + + + serial number associated with a {{block(Component)}}, + {{block(Asset)}}, or {{block(Device)}}. + + + + + + + indication of the status of the spindle for a piece of equipment + when power has been removed and it is free to rotate. + + + + + + + identifier of an individual tool asset. + + + + + + + identifier for the tool group associated with a specific tool. + Commonly used to designate spare tools. + + + + + + + identifier of the tool currently in use for a given `Path`. + **DEPRECATED** in *Version 1.2.0*. See `TOOL_ASSET_ID`. + + + + + + + identifier assigned by the {{block(Controller)}} component to a + cutting tool when in use by a piece of equipment. + + + + + + + reference to the tool offset variables applied to the active cutting + tool. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + data whose meaning may change over time due to changes in the + operation of a piece of equipment or the process being executed on + that piece of equipment. + + + + + + + indication of the reason that {{block(Execution)}} is reporting a + value of `WAIT`. + + + + + + + identifier for the type of wire used as the cutting mechanism in + Electrical Discharge Machining or similar processes. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. **DEPRECATION WARNING**: Recommend using + `FIXTURE_ID` instead. + + + + + + + reference to offset variables for a work piece or part. + + + + + + + Operating System (OS) of a {{block(Component)}}. + + + + + + + embedded software of a {{block(Component)}} . + + + + + + + application on a {{block(Component)}}. + + + + + + + software library on a {{block(Component)}} + + + + + + + hardware of a {{block(Component)}}. + + + + + + + network details of a {{block(Component)}}. + + + + + + + three space angular displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + three space linear displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + {{term(UUID)}} of new device added to an {{term(MTConnect Agent)}}. + + + + + + + {{term(UUID)}} of a device removed from an {{term(MTConnect + Agent)}}. + + + + + + + {{term(UUID)}} of the device whose {{term(metadata)}} has changed. + + + + + + + status of the connection between an {{term(adapter)}} and an + {{term(agent)}}. + + + + + + + originator’s software version of the {{term(adapter)}}. + + + + + + + {{term(URI)}} of the {{term(adapter)}}. + + + + + + + reference version of the MTConnect Standard supported by the + {{term(adapter)}}. + + + + + + + {{term(attachment)}} between a sensor and an entity. + + + + + + + state or condition of a part. + + + + + + + identifier of a process being executed by the device. + + + + + + + identifier given to link the individual occurrence to a group of + related occurrences, such as a process step in a process plan. + + + + + + + identifier given to link the individual occurrence to a class of + processes or process definition. + + + + + + + identifier given to a collection of individual parts. + + + + + + + identifier given to link the individual occurrence to a class of + parts, typically distinguished by a particular part design. + + + + + + + identifier given to a distinguishable, individual part. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. **DEPRECATION WARNING**. Recommend using + `CONTROL_LIMITS`. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. **DEPRECATION WARNING**. Recommend using + `SPECIFICATION_LIMITS`. + + + + + + + set of limits used to trigger warning or alarm indicators. + **DEPRECATION WARNING**. Recommend using `ALARM_LIMITS`. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, load materials, parts, or other items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, unload materials, parts, or other + items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, transfer materials, parts, or other + items from one location to another. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, activate or be performed. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, deactivate or cease. + + + + + + + accumulation of the number of times a cyclic function has attempted + to, or is planned to attempt to execute. + + + + + + + state of a valve is one of open, closed, or transitioning between + the states. + + + + + + + state or operating mode of a {{block(Lock)}}. + + + + + + + particular condition of the process occurrence at a specific time. + + + + + + + particular condition of the part occurrence at a specific time. + + + + + + + state of {{block(Component)}} or {{block(Composition)}} that + describes the automatic or manual operation of the entity. + + + + + + + {{term(data set)}} of the number of {{termplural(Asset)}} of a given + type for a {{term(Device)}}. + + + + + + + actions or activities to be performed in support of a piece of + equipment. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. + + + + + + + interpretation of `PART_COUNT`. + + + + + + + time provided by a timing device at a specific point in time. + + + + + + + name of the host computer supplying data. + + + + + + + number of the TCP/IP or UDP/IP port for the connection endpoint. + + + + + + + indication designating whether a leak has been detected. + + + + + + + present status of the battery. + + + + + + + {{term(UUID)}} of a {{term(feature)}}. {{cite(ISO 10303 AP + 242/239)}}. + + + + + + + detection result of a sensor. + + + + + + + {{block(Event)}} that represents a {{block(Component)}} where the + {{block(EntryDefinition)}} identifies the {{block(Component)}} and + the {{block(CellDefinition)}}s define the + {{block(Component)}}'s observed {{block(DataItem)}}s. + + + + + + + properties of each addressable work offset. + + + + + + + properties of each addressable tool offset. + + + + + + + assessing elements of a {{term(feature)}}. + + + + + + + {{term(UUID)}} of the {{term(characteristic)}}. + + + + + + + class of measurement being performed. {{cite(QIF 3:2018 Section + 6.3)}} + + + + + + + measurement based on the measurement type. + + + + + + + engineering units of the measurement. + + + + + + + pass/fail result of the measurement. + + + + + + + method used to compute {{term(standard uncertainty)}}. + + + + + + + {{term(uncertainty)}} specified by {{block(UncertaintyType)}}. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. + + + + + + + set of limits used to trigger warning or alarm indicators. + + + + + + + references the {{block(CuttingToolLifeCycle)}} + {{block(CuttingItem)}} index related to the + {{property(CuttingItem::indices)}} of the currently active cutting + tool edge. + + + + + + + structured information that allows the unambiguous determination of + an object for purposes of identification and location. {{cite(ISO + 19160-4:2017)}} + + + + + + + active energy source for the {{block(Component)}}. + + + + + + + textual description of the location of an object or activity. + + + + + + + dimension between two surfaces of an object, usually the dimension + of smallest measure, for example an additive layer, or a depth of + cut. + + + + + + + absolute geographic location defined by two coordinates, longitude + and latitude and an elevation. + + + + + + + indication that the piece of equipment has experienced a + communications failure. + + + + + + + indication that the value of the data associated with a measured + value or a calculation is outside of an expected range. + + + + + + + indication that an error occurred in the logic program or + programmable logic controller (PLC) associated with a piece of + equipment. + + + + + + + indication that an error occurred in the motion program associated + with a piece of equipment. + + + + + + + general purpose indication associated with an electronic component + of a piece of equipment or a controller that represents a fault that + is not associated with the operator, program, or hardware. + + + + + + + indication of a fault associated with an actuator. + + + + + + + operational state of an {{block(Interface)}}. + + + + + + + operating state of the service to advance material or feed product + to a piece of equipment from a continuous or bulk source. + + + + + + + operating state of the service to change the type of material or + product being loaded or fed to a piece of equipment. + + + + + + + operating state of the service to remove or retract material or + product. + + + + + + + operating state of the service to change the part or product + associated with a piece of equipment to a different part or product. + + + + + + + operating state of the service to load a piece of material or + product. + + + + + + + operating state of the service to unload a piece of material or + product. + + + + + + + operating state of the service to open a chuck. + + + + + + + operating state of the service to open a door. + + + + + + + operating state of the service to close a chuck. + + + + + + + operating state of the service to close a door. + + + + + + + A user variable + + + + + + + + + The types of measurements available + + + + + + + + Extended tyoe for The sub-types for a measurement + + + + + + + + + + The sub-types for a measurement + + + + + + + relating to or derived in the simplest manner from the fundamental + units or measurements. + + + + + + + indication of the operating state of a mechanism. + + + + + + + measured or reported value of an {{term(observation)}}. + + + + + + + all actions, items, or activities being counted independent of the + outcome. + + + + + + + measurement of alternating voltage or current. If not specified + further in statistic, defaults to RMS voltage. **DEPRECATED** in + *Version 1.6*. + + + + + + + A-Scale weighting factor on the frequency scale. + + + + + + + when multiple locations on a piece of bar stock being feed by a bar + feeder are referenced as the indication of whether the end of that + piece of bar stock has been reached. + + + + + + + actions, items, or activities being counted that do not conform to + specification or expectation. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + B-Scale weighting factor on the frequency scale. + + + + + + + directive value including adjustments such as an offset or + overrides. + + + + + + + amount of material consumed from an object or container during a + manufacturing process. + + + + + + + state of the enabling signal or control logic that enables or + disables the function or operation of the entity. + + + + + + + C-Scale weighting factor on the frequency scale. + + + + + + + elapsed time of a temporary halt of action. + + + + + + + DC current or voltage. **DEPRECATED** in *Version 1.6*. + + + + + + + setting or operator selection used to execute a test mode to confirm + the execution of machine functions. + + + + + + + D-Scale weighting factor on the frequency scale. + + + + + + + relating to the expiration or end of useful life for a material or + other physical item. + + + + + + + relating to the first use of a material or other physical item. + + + + + + + actions, items, or activities being counted that conform to + specification or expectation. + + + + + + + relating to or derived from the last {{term(observation)}}. + + + + + + + relating to momentary activation of a function or a movement. + **DEPRECATION WARNING**: May be deprecated in the future. + + + + + + + indication of the position of a mechanism that may move in a lateral + direction. + + + + + + + scale to measure the elasticity of a surface. + + + + + + + reference to a length type tool offset variable. + + + + + + + state of the power source. + + + + + + + direction of motion of a linear motion. + + + + + + + indication that the subparts of a piece of equipment are under load. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + relating to the primary logic or motion program currently being + executed. + + + + + + + relating to maintenance on the piece of equipment. + + + + + + + indication of the state of an operator controlled interlock that can + inhibit the ability to initiate an unclamp action of an + electronically controlled chuck. + + + + + + + related to the production of a material or other physical item. + + + + + + + maximum value. + + + + + + + minimum value. + + + + + + + scale to measure the resistance to scratching of a surface. + + + + + + + indication of the open or closed state of a mechanism. + + + + + + + no weighting factor on the frequency scale. + + + + + + + piece of equipment that is powered or performing any activity. + + + + + + + relating to the person currently responsible for operating the piece + of equipment. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + overridden value. + + + + + + + piece of equipment is powered and functioning or + {{block(Component)}} that are required to remain on are powered. + + + + + + + main or principle. + + + + + + + position provided by a measurement probe. **DEPRECATION WARNING**: + May be deprecated in the future. + + + + + + + relating to production of a part or product on a piece of equipment. + + + + + + + directive value without offsets and adjustments. + + + + + + + reference to a radial type tool offset variable. + + + + + + + performing an operation faster or in less time than nominal rate. + + + + + + + remaining measure or count of an action, object or activity. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + direction of a rotary motion using the right hand rule convention. + + + + + + + identity of a control program that is used to specify the order of + execution of other programs. + + + + + + + relating to the preparation of a piece of equipment for production + or restoring the piece of equipment to a neutral state after + production. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + standard measure of an object or an action. + + + + + + + boundary when an activity or an event commences. + + + + + + + indication of the activation state of a mechanism represented by a + {{block(Composition)}}. + + + + + + + goal of the operation or process. + + + + + + + relating to the end or completion of an activity or event. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + remaining usable measure of an object or action. + + + + + + + indication of the position of a mechanism that may move in a + vertical direction. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + piece of equipment performing any activity, the equipment is active + and performing a function under load or not. + + + + + + + IPV4 network address of the {{block(Component)}}. + + + + + + + IPV6 network address of the {{block(Component)}}. + + + + + + + Gateway for the {{block(Component)}} network. + + + + + + + SubNet mask for the {{block(Component)}} network. + + + + + + + layer2 Virtual Local Network (VLAN) ID for the {{block(Component)}} + network. + + + + + + + Media Access Control Address. The unique physical address of the + network hardware. + + + + + + + identifies whether the connection type is wireless. + + + + + + + license code to validate or activate the hardware or software. + + + + + + + version of the hardware or software. + + + + + + + date the hardware or software was released for general use. + + + + + + + date the hardware or software was installed. + + + + + + + corporate identity for the maker of the hardware or software. + + + + + + + universally unique identifier as specified in ISO 11578 or RFC 4122. + + + + + + + serial number that uniquely identifies a specific part. + + + + + + + material that is used to produce parts. + + + + + + + group of parts tracked as a lot. + + + + + + + group of parts produced in a batch. + + + + + + + material heat number. + + + + + + + particular part design or model. + + + + + + + group of parts having similarities in geometry, manufacturing + process, and/or functions. + + + + + + + word or set of words by which a part is known, addressed, or + referred to. + + + + + + + step in the process plan that this occurrence corresponds to. + + + + + + + process plan that a process occurrence belongs to. + + + + + + + authorization of a process occurrence. + + + + + + + word or set of words by which a process being executed (process + occurrence) by the device is known, addressed, or referred to. + + + + + + + reference to a ISO 10303 Executable. + + + + + + + associated with the completion of an activity or event. + + + + + + + relating to logic or motion program currently executing. + + + + + + + actions or activities that were attempted , but failed to complete + or resulted in an unexpected or unacceptable outcome. + + + + + + + actions or activities that were attempted, but terminated before + they could be completed. + + + + + + + boundary when an activity or an event terminates. + + + + + + + amount discarded. + + + + + + + amount included in the {{term(part)}}. + + + + + + + {{term(request)}} by an {{block(Interface)}} for a task. + + + + + + + {{term(response)}} by an {{block(Interface)}} to a {{term(request)}} + for a task. + + + + + + + phase or segment of a recipe or program. + + + + + + + phase of a recipe process. + + + + + + + process as part of product production; can be a subprocess of a + larger process. + + + + + + + step of a discrete manufacturing process. + + + + + + + observed as a binary data type. + + + + + + + observed as a boolean data type. + + + + + + + observed as a set containing a restricted number of discrete values + where each discrete value is named and unique. {{cite(ISO + 21961:2003, 013)}} + + + + + + + indicated by the presence or existence of something. + + + + + + + model info of the hardware or software. + + + + + + + + + The sub-types for a measurement + + + + + + + + Extended tyoe for Statistical operations on data + + + + + + + + + + Statistical operations on data + + + + + + + mathematical average value calculated for the data item during the + calculation period. + + + + + + + **DEPRECATED** in *Version 1.6*. ~~A measure of the + "peakedness" of a probability distribution; i.e., the + shape of the distribution curve.~~ + + + + + + + maximum or peak value recorded for the data item during the + calculation period. + + + + + + + middle number of a series of numbers. + + + + + + + minimum value recorded for the data item during the calculation + period. + + + + + + + number in a series of numbers that occurs most often. + + + + + + + difference between the maximum and minimum value of a data item + during the calculation period. Also represents Peak-to-Peak + measurement in a waveform. + + + + + + + mathematical Root Mean Square (RMS) value calculated for the data + item during the calculation period. + + + + + + + statistical Standard Deviation value calculated for the data item + during the calculation period. + + + + + + + + + Statistical operations on data + + + + + + + + Extended tyoe for same as {{property(DataItem::units)}}. See + {{package(Device Information Model)}}. + + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + + Extended tyoe for The units supported for the source equipment that can + be converted into MTC Units. + + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + measure of viscosity. + + + + + + + rotational velocity in degrees per minute. + + + + + + + temperature in Fahrenheit. + + + + + + + feet. + + + + + + + feet per minute. + + + + + + + feet per second. + + + + + + + acceleration in feet per second squared. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in feet. + + + + + + + gallons per minute. + + + + + + + measurement of time in hours. + + + + + + + inches. + + + + + + + inches per minute. + + + + + + + inches per second. + + + + + + + acceleration in inches per second squared. + + + + + + + measure of torque in inch pounds. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in inches. + + + + + + + measurement of temperature. + + + + + + + measurement in kilowatt. + + + + + + + kilowatt hours which is 3.6 mega joules. + + + + + + + measurement of rate of flow of a fluid. + + + + + + + velocity in millimeters per minute. + + + + + + + measurement of time in minutes. + + + + + + + unsupported unit. + + + + + + + US pounds. + + + + + + + pressure in pounds per square inch (PSI). + + + + + + + angle in radians. + + + + + + + velocity in radians per minute. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + pressure in Bar. + + + + + + + pressure in Torr. + + + + + + + pressure in Millimeter of Mercury (mmHg). + + + + + + + pascal per minute. + + + + + + + $$MASS\times GRAVITATIONAL_ACCELERATION$$ (g) given in + `METER/SECOND^2`. + + + + + + + acceleration relative to earth's gravity given in + `METER/SECOND^2`. > Note 1 to entry: At different points on + Earth's surface, the free-fall acceleration ranges from 9.764 + to 9.834 m/s2 (Wikipedia: Gravitational Acceleration). The constant + can be customized depending on the location in the universe. > + Note 2 to entry: In the standard, it is assumed that Earth's + average value of gravitational acceleration is 9.90665 m/s2. + + + + + + + electric charge in ampere hour. + + + + + + + change of geometric volume in cubic foot per hour. + + + + + + + change of geometric volume in cubic foot per minute. + + + + + + + geometric area in inches. + + + + + + + geometric volume in feet. + + + + + + + inch per revolution. + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + + The coordinate system to be used for the position + + + + + + + unchangeable coordinate system that has machine zero as its origin. + + + + + + + coordinate system that represents the working area for a particular + workpiece whose origin is shifted within the `MACHINE` coordinate + system. If the `WORK` coordinates are not currently defined in the + piece of equipment, the `MACHINE` coordinates will be used. + + + + + + + + + Extended tyoe for The reset intervals + + + + + + + + + + The reset intervals + + + + + + + {{term(observation)}} of the {{block(DataItem)}} that is measuring + an action or operation is to be reset upon completion of that action + or operation. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 12-month period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 24-hour period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is not reset and + accumulates for the entire life of the piece of equipment. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset upon + completion of a maintenance event. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a monthly period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset when + power was applied to the piece of equipment after a planned or + unplanned interruption of power has occurred. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a work shift. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 7-day period. + + + + + + + + + The reset intervals + + + + + + + + + The document version + + + + + + + time the file was created. + + + + + + + Indicates that this was a test document + + + + + + + The unique instance identifier of this agent process + + + + + + + The sender of the message + + + + + + + A timestamp in 8601 format of the last update of the Device + information for any device + + + + + + + + The number of assets + + + + + + + + + + + indicates if the MTConnect Agent is validating against the normative + model. + + + + + + + + {{block(AssetCounts)}} groups {{block(AssetCount)}} entities. + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + The type of asset + + + + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the data + management within the {{term(agent)}}. + + + + + + + {{block(AssetCounts)}} groups {{block(AssetCount)}} entities. + + + + + + + + + The size of the agent's buffer. + + + + + + + The maximum number of assets + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + indicates if the MTConnect Agent is validating against the normative + model. + + + + + + + + root entity of an {{term(MTConnectDevices Response Document)}} that + contains the {{term(Device Information Model)}} of one or more + {{block(Device)}} entities. + ![MTConnectDevices](figures/MTConnectDevices.png + "MTConnectDevices"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectDevices)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the + data management within the {{term(agent)}}. + + + + + + + This section provides semantic information for the {{block(Device)}} + types. + + + + + + + + + The station id for this device + + + + + + + + The ISO 841 classification for the device + + + + + + + + The model name + + + + + + + + This section provides semantic information for the {{block(Device)}} + types. + + + + + + + Description + + + + + + + Description + + + + + + + + + Description + + + + + + + See {{sect(Description)}}. + + + + + + + technical information about an entity describing its physical + layout, functional characteristics, and relationships with other + entities. + + + + + + + + + + + + {{block(Components)}} groups one or more {{block(Component)}} + entities. + + + + + + + Compositions Model + + + + + + + References Model + + + + + + + + unique identifier for the power source. + + + + + + + The device manufacturer component name + + + + + + + The rate at which the data is sampled from the component + + + + + + + DEPRECATED: The rate at which the data is sampled from the component + + + + + + + + Description + + + + + + + The descriptive information. This can be manufacturer specific + + + + + + + The content of the description can text or XML elements + + + + + + + + name of the material manufacturer. + + + + + + + The model + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + leaf {{block(Component)}} composed of a storage or mounting location + for a tool associated with a {{block(Turret)}}, + {{block(GangToolBar)}}, or {{block(ToolRack)}}. + + + + + + + + An abstract component that has an optional uuid + + + + + + + + The component's universally unique id. + + + + + + + identifier of the maintenance activity. + + + + + + + + + + An abstract component that has an optional uuid + + + + + + + {{block(Components)}} groups one or more {{block(Component)}} entities. + + + + + + + + + + Description + + + + + + + + DEPRECATED: The device's ISO-841 classification + + + + + + + The components universally unique id. This can be composed of the + manufactures id or name and the serial number. + + + + + + + identifier of the maintenance activity. + + + + + + + MTConnect version of the {{term(Device Information Model)}} used + to configure the information to be published for a piece of + equipment in an {{term(MTConnect Response Document)}}. + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + abstract {{block(Component)}} composed of removable part(s) of a piece + of equipment that provides supplementary or extended functionality. + + + + + + + + + + abstract {{block(Component)}} composed of removable part(s) of a piece + of equipment that provides supplementary or extended functionality. + + + + + + + See {{sect(Axis)}}. + + + + + + + + + + See {{sect(Axis)}}. + + + + + + + {{block(Loader)}} that delivers bar stock to a piece of equipment. + + + + + + + + + + {{block(Loader)}} that delivers bar stock to a piece of equipment. + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(System)}} that provides distribution and management of fluids + that remove heat from a piece of equipment. + + + + + + + + + + {{block(System)}} that provides distribution and management of fluids + that remove heat from a piece of equipment. + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(Component)}} that observes the surroundings of another + {{block(Component)}}. > Note: {{block(Environmental)}} **SHOULD** be + organized by {{block(Auxillaries)}}, {{block(Systems)}} or + {{block(Parts)}} depending on the relationship to the + {{block(Component)}}. + + + + + + + + + + {{block(Component)}} that observes the surroundings of another + {{block(Component)}}. > Note: {{block(Environmental)}} **SHOULD** be + organized by {{block(Auxillaries)}}, {{block(Systems)}} or + {{block(Parts)}} depending on the relationship to the + {{block(Component)}}. + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(System)}} that provides movement and distribution of pressurized + liquid throughout the piece of equipment. + + + + + + + + + + {{block(System)}} that provides movement and distribution of pressurized + liquid throughout the piece of equipment. + + + + + + + {{block(Component Types::Axis)}} that provides prismatic motion along a + fixed axis. + + + + + + + + + + {{block(Component Types::Axis)}} that provides prismatic motion along a + fixed axis. + + + + + + + {{block(Auxiliary)}} that provides movement and distribution of + materials, parts, tooling, and other items to or from a piece of + equipment. + + + + + + + + + + {{block(Auxiliary)}} that provides movement and distribution of + materials, parts, tooling, and other items to or from a piece of + equipment. + + + + + + + {{block(System)}} that provides distribution and management of fluids + used to lubricate portions of the piece of equipment. + + + + + + + + + + {{block(System)}} that provides distribution and management of fluids + used to lubricate portions of the piece of equipment. + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(Resource)}} composed of an individual or individuals who either + control, support, or otherwise interface with a piece of equipment. + + + + + + + + + + {{block(Resource)}} composed of an individual or individuals who either + control, support, or otherwise interface with a piece of equipment. + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(Power)}} was **DEPRECATED** in *MTConnect Version 1.1* and was + replaced by {{block(Availability)}} data item type. + + + + + + + + + + {{block(Power)}} was **DEPRECATED** in *MTConnect Version 1.1* and was + replaced by {{block(Availability)}} data item type. + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + abstract {{block(Component)}} composed of material or personnel involved + in a manufacturing process. + + + + + + + + + + abstract {{block(Component)}} composed of material or personnel involved + in a manufacturing process. + + + + + + + {{block(Component Types::Axis)}} that provides rotation about a fixed + axis. + + + + + + + + + + {{block(Component Types::Axis)}} that provides rotation about a fixed + axis. + + + + + + + This section provides semantic information for the + {{block(SensorConfiguration)}} entity. {{term(sensor)}} is a unique type + of a piece of equipment. A {{term(sensor)}} is typically comprised of + two major components: a {{term(sensor unit)}} that provides signal + processing, conversion, and communications and the {{termplural(sensing + element)}} that provides a signal or measured value. The {{term(sensor + unit)}} is modeled as a {{term(lower level)}} {{block(Component)}} + called {{block(Sensor)}}. The {{term(sensing element)}} may be modeled + as a {{block(Composition)}} element of a {{block(Sensor)}} element and + the measured value would be modeled as a {{block(DataItem)}} (See + {{sect(DataItems)}} for more information on {{block(DataItem)}} + elements). Each {{term(sensor unit)}} may have multiple + {{termplural(sensing element)}}; each representing the data for a + variety of measured values. ![Sensing Element provided as a DataItem + Example](figures/Sensing%20Element%20provided%20as%20a%20DataItem%20Example.png "Sensing Element provided as a DataItem Example"){: width="0.8"} > Note: See {{lst(example-of-sensing-element-provided-as-data-item-associated-with-a-component)}} for an {{term(XML)}} example. When a {{term(sensor unit)}} is modeled as a {{block(Component)}} or as a separate piece of equipment, it may provide additional configuration information for the {{termplural(sensor element)}} and the {{term(sensor unit)}} itself. ![Sensor for Rotary Axis Example](figures/Sensor%20for%20Rotary%20Axis%20Example.png "Sensor for Rotary Axis Example"){: width="0.8"} > Note: If a {{block(Sensor)}} provides vibration measurement data for the spindle on a piece of equipment, it could be modeled as a {{block(Sensor)}} for rotary axis named `C`. See {{lst(example-of-sensor-for-rotary-axis)}} for an {{term(XML)}} example. ![Sensor unit with Sensing Elements Example](figures/Sensor%20unit%20with%20Sensing%20Elements%20Example.png "Sensor unit with Sensing Elements Example"){: width="0.8"} > Note: If a {{block(Sensor)}} provides measurement data for multiple {{block(Component)}} elements within a piece of equipment and is not associated with any particular {{block(Component)}}, it **MAY** be modeled as an independent {{block(Component)}} and the data associated with measurements are associated with their associated {{block(Component)}} entities. See {{lst(example-of-sensor-unit-with-sensing-element)}} for an {{term(XML)}} example. {{block(Configuration)}} data provides information required for maintenance and support of the sensor. When {{block(Sensor)}} represents the {{term(sensor unit)}} for multiple {{term(sensing element)}}(s), each sensing element is represented by a {{block(Channel)}}. The {{term(sensor unit)}} itself and each {{block(Channel)}} representing one {{term(sensing element)}} **MAY** have its own configuration data. ![Sensor Configuration Example](figures/Sensor%20Configuration%20Example.png "Sensor Configuration Example"){: width="0.8"} > Note: See {{lst(example-of-configuration-data-for-sensor)}} for an {{term(XML)}} example. + + + + + + + + + + This section provides semantic information for the + {{block(SensorConfiguration)}} entity. {{term(sensor)}} is a unique type + of a piece of equipment. A {{term(sensor)}} is typically comprised of + two major components: a {{term(sensor unit)}} that provides signal + processing, conversion, and communications and the {{termplural(sensing + element)}} that provides a signal or measured value. The {{term(sensor + unit)}} is modeled as a {{term(lower level)}} {{block(Component)}} + called {{block(Sensor)}}. The {{term(sensing element)}} may be modeled + as a {{block(Composition)}} element of a {{block(Sensor)}} element and + the measured value would be modeled as a {{block(DataItem)}} (See + {{sect(DataItems)}} for more information on {{block(DataItem)}} + elements). Each {{term(sensor unit)}} may have multiple + {{termplural(sensing element)}}; each representing the data for a + variety of measured values. ![Sensing Element provided as a DataItem + Example](figures/Sensing%20Element%20provided%20as%20a%20DataItem%20Example.png "Sensing Element provided as a DataItem Example"){: width="0.8"} > Note: See {{lst(example-of-sensing-element-provided-as-data-item-associated-with-a-component)}} for an {{term(XML)}} example. When a {{term(sensor unit)}} is modeled as a {{block(Component)}} or as a separate piece of equipment, it may provide additional configuration information for the {{termplural(sensor element)}} and the {{term(sensor unit)}} itself. ![Sensor for Rotary Axis Example](figures/Sensor%20for%20Rotary%20Axis%20Example.png "Sensor for Rotary Axis Example"){: width="0.8"} > Note: If a {{block(Sensor)}} provides vibration measurement data for the spindle on a piece of equipment, it could be modeled as a {{block(Sensor)}} for rotary axis named `C`. See {{lst(example-of-sensor-for-rotary-axis)}} for an {{term(XML)}} example. ![Sensor unit with Sensing Elements Example](figures/Sensor%20unit%20with%20Sensing%20Elements%20Example.png "Sensor unit with Sensing Elements Example"){: width="0.8"} > Note: If a {{block(Sensor)}} provides measurement data for multiple {{block(Component)}} elements within a piece of equipment and is not associated with any particular {{block(Component)}}, it **MAY** be modeled as an independent {{block(Component)}} and the data associated with measurements are associated with their associated {{block(Component)}} entities. See {{lst(example-of-sensor-unit-with-sensing-element)}} for an {{term(XML)}} example. {{block(Configuration)}} data provides information required for maintenance and support of the sensor. When {{block(Sensor)}} represents the {{term(sensor unit)}} for multiple {{term(sensing element)}}(s), each sensing element is represented by a {{block(Channel)}}. The {{term(sensor unit)}} itself and each {{block(Channel)}} representing one {{term(sensing element)}} **MAY** have its own configuration data. ![Sensor Configuration Example](figures/Sensor%20Configuration%20Example.png "Sensor Configuration Example"){: width="0.8"} > Note: See {{lst(example-of-configuration-data-for-sensor)}} for an {{term(XML)}} example. + + + + + + + Description + + + + + + + + + + Description + + + + + + + abstract {{block(Component)}} that is permanently integrated into the + piece of equipment. + + + + + + + + + + abstract {{block(Component)}} that is permanently integrated into the + piece of equipment. + + + + + + + {{block(Auxiliary)}} that manages, positions, stores, and delivers + tooling within a piece of equipment. + + + + + + + + + + {{block(Auxiliary)}} that manages, positions, stores, and delivers + tooling within a piece of equipment. + + + + + + + {{block(Auxiliary)}} that removes manufacturing byproducts from a piece + of equipment. + + + + + + + + + + {{block(Auxiliary)}} that removes manufacturing byproducts from a piece + of equipment. + + + + + + + {{block(Component)}} composed of part(s) comprising the rigid bodies of + the piece of equipment. + + + + + + + + + + {{block(Component)}} composed of part(s) comprising the rigid bodies of + the piece of equipment. + + + + + + + {{block(Structure)}} that provides a connection between + {{block(Component)}} entities. + + + + + + + + + + {{block(Structure)}} that provides a connection between + {{block(Component)}} entities. + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + abstract {{block(Component)}} composed of a manufacturing process being + executed on a piece of equipment. + + + + + + + + + + abstract {{block(Component)}} composed of a manufacturing process being + executed on a piece of equipment. + + + + + + + Description + + + + + + + + + + Description + + + + + + + Example + + + + + + + + + + Example + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(System)}} that evacuates gases and liquids from an enclosed and + sealed space to a controlled negative pressure or a molecular density + below the prevailing atmospheric level. + + + + + + + + + + {{block(System)}} that evacuates gases and liquids from an enclosed and + sealed space to a controlled negative pressure or a molecular density + below the prevailing atmospheric level. + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + abstract {{block(Component)}} composed of a {{term(part)}} being + processed by a piece of equipment. + + + + + + + + + + abstract {{block(Component)}} composed of a {{term(part)}} being + processed by a piece of equipment. + + + + + + + {{block(Component)}} that physically prohibits a {{block(Device)}} or + {{block(Component)}} from opening or operating. + + + + + + + + + + {{block(Component)}} that physically prohibits a {{block(Device)}} or + {{block(Component)}} from opening or operating. + + + + + + + {{block(Component)}} that provides an axis of rotation for the purpose + of rapidly rotating a part or a tool to provide sufficient surface speed + for cutting operations. {{block(Spindle)}} was **DEPRECATED** in + *MTConnect Version 1.1* and was replaced by {{block(RotaryMode)}}. + + + + + + + + + + {{block(Component)}} that provides an axis of rotation for the purpose + of rapidly rotating a part or a tool to provide sufficient surface speed + for cutting operations. {{block(Spindle)}} was **DEPRECATED** in + *MTConnect Version 1.1* and was replaced by {{block(RotaryMode)}}. + + + + + + + {{block(Component)}} composed of a sensor or an instrument that measures + temperature. {{block(Thermostat)}} was **DEPRECATED** in *MTConnect + Version 1.2* and was replaced by {{block(Temperature)}}. + + + + + + + + + + {{block(Component)}} composed of a sensor or an instrument that measures + temperature. {{block(Thermostat)}} was **DEPRECATED** in *MTConnect + Version 1.2* and was replaced by {{block(Temperature)}}. + + + + + + + {{block(Component)}} composed of a sensor or an instrument that measures + the amount and/or frequency of vibration within a system. + {{block(Vibration)}} was **DEPRECATED** in *MTConnect Version 1.2* and + was replaced by {{block(Displacement)}}, {{block(Frequency)}} etc. + + + + + + + + + + {{block(Component)}} composed of a sensor or an instrument that measures + the amount and/or frequency of vibration within a system. + {{block(Vibration)}} was **DEPRECATED** in *MTConnect Version 1.2* and + was replaced by {{block(Displacement)}}, {{block(Frequency)}} etc. + + + + + + + leaf {{block(Component)}} composed of a mechanism that holds a part or + stock material in place. + + + + + + + + + + leaf {{block(Component)}} composed of a mechanism that holds a part or + stock material in place. + + + + + + + leaf {{block(Component)}} that produces a current of air. + + + + + + + + + + leaf {{block(Component)}} that produces a current of air. + + + + + + + leaf {{block(Component)}} that flattens or spreading materials. + + + + + + + + + + leaf {{block(Component)}} that flattens or spreading materials. + + + + + + + leaf {{block(Component)}} composed of a mechanism or wheel that turns in + a frame or block and serves to change the direction of or to transmit + force. + + + + + + + + + + leaf {{block(Component)}} composed of a mechanism or wheel that turns in + a frame or block and serves to change the direction of or to transmit + force. + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is + awaiting transfer from a {{block(ToolMagazine)}} to {{term(spindle)}} or + {{block(Turret)}}. + + + + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is + awaiting transfer from a {{block(ToolMagazine)}} to {{term(spindle)}} or + {{block(Turret)}}. + + + + + + + leaf {{block(Component)}} that provides power to electric mechanisms. + + + + + + + + + + leaf {{block(Component)}} that provides power to electric mechanisms. + + + + + + + leaf {{block(Component)}} that allows material to flow for the purpose + of drainage from, for example, a vessel or tank. + + + + + + + + + + leaf {{block(Component)}} that allows material to flow for the purpose + of drainage from, for example, a vessel or tank. + + + + + + + leaf {{block(Component)}} composed of a mechanical structure that + transforms rotary motion into linear motion. + + + + + + + + + + leaf {{block(Component)}} composed of a mechanical structure that + transforms rotary motion into linear motion. + + + + + + + leaf {{block(Component)}} composed of a pump or other mechanism that + reduces volume and increases pressure of gases in order to condense the + gases to drive pneumatically powered pieces of equipment. + + + + + + + + + + leaf {{block(Component)}} composed of a pump or other mechanism that + reduces volume and increases pressure of gases in order to condense the + gases to drive pneumatically powered pieces of equipment. + + + + + + + leaf {{block(Component)}} composed of an inclined channel that conveys + material. + + + + + + + + + + leaf {{block(Component)}} composed of an inclined channel that conveys + material. + + + + + + + leaf {{block(Component)}} that turns on or off an electric current or + makes or breaks a circuit. + + + + + + + + + + leaf {{block(Component)}} that turns on or off an electric current or + makes or breaks a circuit. + + + + + + + leaf {{block(Component)}} that provides or applies a stretch or strain + to another mechanism. + + + + + + + + + + leaf {{block(Component)}} that provides or applies a stretch or strain + to another mechanism. + + + + + + + leaf {{block(Component)}} composed of $$H_2 O$$. + + + + + + + + + + leaf {{block(Component)}} composed of $$H_2 O$$. + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + leaf {{block(Component)}} that provides a signal or measured value. + + + + + + + + + + leaf {{block(Component)}} that provides a signal or measured value. + + + + + + + leaf {{block(Component)}} composed of a heat exchange system that uses a + fluid to transfer heat to the atmosphere. + + + + + + + + + + leaf {{block(Component)}} composed of a heat exchange system that uses a + fluid to transfer heat to the atmosphere. + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that has + to be removed from a {{block(ToolMagazine)}} or {{block(Turret)}} to a + location outside of the piece of equipment. + + + + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that has + to be removed from a {{block(ToolMagazine)}} or {{block(Turret)}} to a + location outside of the piece of equipment. + + + + + + + leaf {{block(Component)}} that holds a part, stock material, or any + other item in place. + + + + + + + + + + leaf {{block(Component)}} that holds a part, stock material, or any + other item in place. + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is + awaiting transfer to a {{block(ToolMagazine)}} or {{block(Turret)}} from + outside of the piece of equipment. + + + + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is + awaiting transfer to a {{block(ToolMagazine)}} or {{block(Turret)}} from + outside of the piece of equipment. + + + + + + + leaf {{block(Component)}} that slows or stops a moving object by the + absorption or transfer of the energy of momentum, usually by means of + friction, electrical force, or magnetic force. + + + + + + + + + + leaf {{block(Component)}} that slows or stops a moving object by the + absorption or transfer of the energy of momentum, usually by means of + friction, electrical force, or magnetic force. + + + + + + + leaf {{block(Component)}} composed of a storage or mounting location for + a tool associated with a {{block(Turret)}}, {{block(GangToolBar)}}, or + {{block(ToolRack)}}. + + + + + + + + + + leaf {{block(Component)}} composed of a storage or mounting location for + a tool associated with a {{block(Turret)}}, {{block(GangToolBar)}}, or + {{block(ToolRack)}}. + + + + + + + leaf {{block(Component)}} composed of a chamber or bin in which + materials are stored temporarily, typically being filled through the top + and dispensed through the bottom. + + + + + + + + + + leaf {{block(Component)}} composed of a chamber or bin in which + materials are stored temporarily, typically being filled through the top + and dispensed through the bottom. + + + + + + + leaf {{block(Component)}} composed of an endless flexible band that + transmits motion for a piece of equipment or conveys materials and + objects. + + + + + + + + + + leaf {{block(Component)}} composed of an endless flexible band that + transmits motion for a piece of equipment or conveys materials and + objects. + + + + + + + leaf {{block(Component)}} that physically moves a tool from one location + to another. + + + + + + + + + + leaf {{block(Component)}} that physically moves a tool from one location + to another. + + + + + + + leaf {{block(Component)}} composed of a rotary storage unit for + material. + + + + + + + + + + leaf {{block(Component)}} composed of a rotary storage unit for + material. + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that has + been removed from {{term(spindle)}} or {{block(Turret)}} and awaiting + for return to a {{block(ToolMagazine)}}. + + + + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that has + been removed from {{term(spindle)}} or {{block(Turret)}} and awaiting + for return to a {{block(ToolMagazine)}}. + + + + + + + leaf {{block(Component)}} composed of interconnected series of objects + that band together and are used to transmit motion for a piece of + equipment or to convey materials and objects. + + + + + + + + + + leaf {{block(Component)}} composed of interconnected series of objects + that band together and are used to transmit motion for a piece of + equipment or to convey materials and objects. + + + + + + + leaf {{block(Component)}} composed of an electronic component or circuit + that amplifies power, electric current, or voltage. + + + + + + + + + + leaf {{block(Component)}} composed of an electronic component or circuit + that amplifies power, electric current, or voltage. + + + + + + + leaf {{block(Component)}} generally composed of an open container. + + + + + + + + + + leaf {{block(Component)}} generally composed of an open container. + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is no + longer usable for removal from a {{block(ToolMagazine)}} or + {{block(Turret)}}. + + + + + + + + + + leaf {{block(Component)}} that is a {{block(Pot)}} for a tool that is no + longer usable for removal from a {{block(ToolMagazine)}} or + {{block(Turret)}}. + + + + + + + leaf {{block(Component)}} composed of a viscous liquid. + + + + + + + + + + leaf {{block(Component)}} composed of a viscous liquid. + + + + + + + leaf {{block(Component)}} composed of a surface for holding an object or + material. + + + + + + + + + + leaf {{block(Component)}} composed of a surface for holding an object or + material. + + + + + + + leaf {{block(Component)}} that breaks material into smaller pieces. + + + + + + + + + + leaf {{block(Component)}} that breaks material into smaller pieces. + + + + + + + leaf {{block(Component)}} that halts or controls the flow of a liquid, + gas, or other material through a passage, pipe, inlet, or outlet. + + + + + + + + + + leaf {{block(Component)}} that halts or controls the flow of a liquid, + gas, or other material through a passage, pipe, inlet, or outlet. + + + + + + + leaf {{block(Component)}} composed of a tool storage location associated + with a {{block(ToolMagazine)}} or {{block(AutomaticToolChanger)}}. + + + + + + + + + + leaf {{block(Component)}} composed of a tool storage location associated + with a {{block(ToolMagazine)}} or {{block(AutomaticToolChanger)}}. + + + + + + + leaf {{block(Component)}} that transforms electric energy from a source + to a secondary circuit. + + + + + + + + + + leaf {{block(Component)}} that transforms electric energy from a source + to a secondary circuit. + + + + + + + leaf {{block(Component)}} that emits a type of radiation. + + + + + + + + + + leaf {{block(Component)}} that emits a type of radiation. + + + + + + + leaf {{block(Component)}} generally composed of an enclosed container. + + + + + + + + + + leaf {{block(Component)}} generally composed of an enclosed container. + + + + + + + leaf {{block(Component)}} that measures position. + + + + + + + + + + leaf {{block(Component)}} that measures position. + + + + + + + leaf {{block(Component)}} composed of one or more cells in which + chemical energy is converted into electricity and used as a source of + power. + + + + + + + + + + leaf {{block(Component)}} composed of one or more cells in which + chemical energy is converted into electricity and used as a source of + power. + + + + + + + leaf {{block(Component)}} that interrupts an electric circuit. + + + + + + + + + + leaf {{block(Component)}} that interrupts an electric circuit. + + + + + + + leaf {{block(Component)}} that converts electrical, pneumatic, or + hydraulic energy into mechanical energy. + + + + + + + + + + leaf {{block(Component)}} that converts electrical, pneumatic, or + hydraulic energy into mechanical energy. + + + + + + + leaf {{block(Component)}} that dispenses liquid or powered materials. + + + + + + + + + + leaf {{block(Component)}} that dispenses liquid or powered materials. + + + + + + + leaf {{block(Component)}} composed of an electromechanical actuator that + produces deflection of a beam of light or energy in response to electric + current through its coil in a magnetic field. + + + + + + + + + + leaf {{block(Component)}} composed of an electromechanical actuator that + produces deflection of a beam of light or energy in response to electric + current through its coil in a magnetic field. + + + + + + + leaf {{block(Component)}} that raises, drives, exhausts, or compresses + fluids or gases by means of a piston, plunger, or set of rotating vanes. + + + + + + + + + + leaf {{block(Component)}} that raises, drives, exhausts, or compresses + fluids or gases by means of a piston, plunger, or set of rotating vanes. + + + + + + + leaf {{block(Component)}} that strengthens, support, or fastens objects + in place. + + + + + + + + + + leaf {{block(Component)}} that strengthens, support, or fastens objects + in place. + + + + + + + leaf {{block(Component)}} that measures linear motion or position. + **DEPRECATION WARNING** : May be deprecated in the future. Recommend + using {{block(Encoder)}}. + + + + + + + + + + leaf {{block(Component)}} that measures linear motion or position. + **DEPRECATION WARNING** : May be deprecated in the future. Recommend + using {{block(Encoder)}}. + + + + + + + leaf {{block(Component)}} composed of an object or material on which a + form of work is performed. + + + + + + + + + + leaf {{block(Component)}} composed of an object or material on which a + form of work is performed. + + + + + + + Description + + + + + + + + + + Description + + + + + + + {{block(Component)}} that provides information related to an individual + {{term(feature)}}. + + + + + + + + + + {{block(Component)}} that provides information related to an individual + {{term(feature)}}. + + + + + + + system that circulates air or regulates airflow without altering + temperature or humidity. + + + + + + + + + + system that circulates air or regulates airflow without altering + temperature or humidity. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Structure)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Structure)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Interface)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Interface)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Auxiliary)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Auxiliary)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(System)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(System)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Adapter)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Adapter)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Resource)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Resource)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Component + Types::Axis)}} types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Component + Types::Axis)}} types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Process)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Process)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Part)}} + types. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Part)}} + types. + + + + + + + {{block(Resources)}} that {{termplural(organize)}} {{block(Material)}} + types. + + + + + + + + + + {{block(Resources)}} that {{termplural(organize)}} {{block(Material)}} + types. + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Controller)}} + entities. + + + + + + + + + + {{block(Component)}} that {{termplural(organize)}} {{block(Controller)}} + entities. + + + + + + + Compositions Model + + + + + + + Description + + + + + + + + + Extended tyoe for The vocab for the type of composition + + + + + + + + + + The vocab for the type of composition + + + + + + + {{block(Composition)}} composed of a mechanism that moves or + controls a mechanical part of a piece of equipment. It takes energy + usually provided by air, electric current, or liquid and converts + the energy into some kind of motion. + + + + + + + {{block(Composition)}} composed of an electronic component or + circuit that amplifies power, electric current, or voltage. + + + + + + + {{block(Composition)}} composed of a mechanical structure that + transforms rotary motion into linear motion. + + + + + + + {{block(Composition)}} composed of an endless flexible band that + transmits motion for a piece of equipment or conveys materials and + objects. + + + + + + + {{block(Composition)}} composed of a mechanism that slows down or + stops a moving object by the absorption or transfer of the energy of + momentum, usually by means of friction, electrical force, or + magnetic force. + + + + + + + {{block(Composition)}} composed of an interconnected series of + objects that band together and transmit motion for a piece of + equipment or to convey materials and objects. + + + + + + + {{block(Composition)}} composed of a mechanism that breaks material + into smaller pieces. + + + + + + + {{block(Composition)}} composed of a mechanism that holds a part, + stock material, or any other item in place. + + + + + + + {{block(Composition)}} composed of an inclined channel that conveys + material. + + + + + + + {{block(Composition)}} composed of a mechanism that interrupts an + electric circuit. + + + + + + + {{block(Composition)}} composed of a mechanism that strengthens, + supports, or fastens objects in place. + + + + + + + {{block(Composition)}} composed of a pump or other mechanism that + reduces volume and increases pressure of gases in order to condense + the gases to drive pneumatically powered pieces of equipment. + + + + + + + {{block(Composition)}} composed of a mechanical mechanism or closure + that covers a physical access portal into a piece of equipment + allowing or restricting access to other parts of the equipment. + + + + + + + {{block(Composition)}} composed of a mechanism that allows material + to flow for the purpose of drainage from, for example, a vessel or + tank. + + + + + + + {{block(Composition)}} composed of a mechanism that measures rotary + position. + + + + + + + {{block(Composition)}} composed of a mechanism that emits a type of + radiation. + + + + + + + {{block(Composition)}} composed of a mechanism that dispenses liquid + or powered materials. + + + + + + + {{block(Composition)}} composed of a mechanism that produces a + current of air. + + + + + + + {{block(Composition)}} composed of a substance or structure that + allows liquids or gases to pass through to remove suspended + impurities or to recover solids. + + + + + + + {{block(Composition)}} composed of an electromechanical actuator + that produces deflection of a beam of light or energy in response to + electric current through its coil in a magnetic field. + + + + + + + {{block(Composition)}} composed of a mechanism that holds a part, + stock material, or any other item in place. + + + + + + + {{block(Composition)}} composed of a chamber or bin that stores + materials temporarily, typically being filled through the top and + dispensed through the bottom. + + + + + + + {{block(Composition)}} composed of a mechanism that measures linear + motion or position. + + + + + + + {{block(Composition)}} composed of a mechanism that converts + electrical, pneumatic, or hydraulic energy into mechanical energy. + + + + + + + {{block(Composition)}} composed of a viscous liquid. + + + + + + + {{block(Composition)}} composed of a unit that provides power to + electric mechanisms. + + + + + + + {{block(Composition)}} composed of a mechanism or wheel that turns + in a frame or block and serves to change the direction of or to + transmit force. + + + + + + + {{block(Composition)}} composed of an apparatus that raises, drives, + exhausts, or compresses fluids or gases by means of a piston, + plunger, or set of rotating vanes. + + + + + + + {{block(Composition)}} composed of a rotary storage unit for + material. + + + + + + + {{block(Composition)}} composed of a mechanism that provides a + signal or measured value. + + + + + + + {{block(Composition)}} composed of a mechanism that flattens or + spreads materials. + + + + + + + {{block(Composition)}} composed of one or more cells that converts + chemical energy to electricity and serves as a source of power. + + + + + + + {{block(Composition)}} composed of a mechanism that turns on or off + an electric current or makes or breaks a circuit. + + + + + + + {{block(Composition)}} composed of a surface that holds an object or + material. + + + + + + + {{block(Composition)}} composed of a receptacle or container that + holds material. + + + + + + + {{block(Composition)}} composed of a mechanism that provides or + applies a stretch or strain to another mechanism. + + + + + + + {{block(Composition)}} composed of a mechanism that transforms + electric energy from a source to a secondary circuit. + + + + + + + {{block(Composition)}} composed of a mechanism that halts or + controls the flow of a liquid, gas, or other material through a + passage, pipe, inlet, or outlet. + + + + + + + {{block(Composition)}} composed of a container for liquid or + powdered materials. + + + + + + + {{block(Composition)}} composed of a fluid. + + + + + + + {{block(Composition)}} composed of a string like piece or filament + of relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + {{block(Composition)}} composed of an object or material on which a + form of work is performed. + + + + + + + {{block(Composition)}} composed of a heat exchange system that uses + a fluid to transfer heat to the atmosphere. + + + + + + + {{block(Composition)}} composed of a tool storage location + associated with a {{block(ToolMagazine)}} or + {{block(AutomaticToolChanger)}}. + + + + + + + {{block(Composition)}} composed of a storage or mounting location + for a tool associated with a {{block(Turret)}}, + {{block(GangToolBar)}}, or {{block(ToolRack)}}. + + + + + + + {{block(Composition)}} composed of a mechanism that physically moves + a tool from one location to another. + + + + + + + {{block(Pot)}} for a tool awaiting transfer from a + {{block(ToolMagazine)}} to {{term(spindle)}} or {{block(Turret)}}. + + + + + + + {{block(Pot)}} for a tool removed from {{term(spindle)}} or + {{block(Turret)}} and awaiting for return to a + {{block(ToolMagazine)}}. + + + + + + + {{block(Pot)}} for a tool awaiting transfer to a + {{block(ToolMagazine)}} or {{block(Turret)}} from outside of the + piece of equipment. + + + + + + + {{block(Pot)}} for a tool to be removed from a + {{block(ToolMagazine)}} or {{block(Turret)}} to a location outside + of the piece of equipment. + + + + + + + {{block(Pot)}} for a tool that is no longer usable for removal from + a {{block(ToolMagazine)}} or {{block(Turret)}}. + + + + + + + + + The vocab for the type of composition + + + + + + + + Description + + + + + + + See {{sect(Description)}}. + + + + + + + technical information about an entity describing its physical + layout, functional characteristics, and relationships with other + entities. + + + + + + + + unique identifier for the power source. + + + + + + + The composition's universally unique id. + + + + + + + identifier of the maintenance activity. + + + + + + + The type of composition + + + + + + + + A reference to an identifier + + + + + + + + References Model + + + + + + + + + + Description + + + + + + A reference to an id in the MTConnectDevices model + + + + + + + identifier of the maintenance activity. + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + Description + + + + + + + + + + Description + + + + + + + data type of Entry value + + + + + + + + Abstract configuration + + + + + + + Abstract configuration + + + + + + + The configuration data associated with this component. + + + + + + + + + + An entry for a configuration element with three dimensional values + + + + + + + + the key + + + + + + + + + + A Configuration element with three dimensional value for 'X Y + Z' + + + + + + + Constraints for Entry Values + + + + + + + + + A Configuration element with three dimensional value for 'A B + C' + + + + + + + Constraints for Entry Values + + + + + + + + + The time the calibration was preformed + + + + + + + + The time the next calibration should be preformed + + + + + + + + The initials of the person doing the calibration + + + + + + + + The firmware version of this sensor + + + + + + + + The channel number + + + + + + + + See {{block(SensorConfiguration)}}. + + + + + + + + + Version number for the sensor unit as specified by the + manufacturer. + + + + + + + Date upon which the {{term(sensor unit)}} was last calibrated to + the {{term(sensor element)}}. + + + + + + + Date upon which the {{term(sensor element)}} is next scheduled + to be calibrated with the {{term(sensor unit)}}. + + + + + + + The initials of the person verifying the validity of the + calibration data. + + + + + + + {{block(Channels)}} groups one or more {{block(Channel)}} + entities. See {{block(Channel)}}. + + + + + + + + + + + See {{block(SensorConfiguration)}}. + + + + + + + {{block(Channels)}} groups one or more {{block(Channel)}} entities. See + {{block(Channel)}}. + + + + + + + Description + + + + + + + + + Description + + + + + + + See {{sect(Description)}}. + + + + + + + Date upon which the {{term(sensor unit)}} was last calibrated to the + {{term(sensor element)}}. + + + + + + + Date upon which the {{term(sensor element)}} is next scheduled to be + calibrated with the {{term(sensor unit)}}. + + + + + + + The initials of the person verifying the validity of the calibration + data. + + + + + + + + The channel id + + + + + + + identifier of the maintenance activity. + + + + + + + + The peak value + + + + + + + + {{block(Specifications)}} groups one or more {{block(Specification)}} + entities. See {{package(Specifications)}}. + + + + + + + + + + + + + + {{block(Specifications)}} groups one or more {{block(Specification)}} + entities. See {{package(Specifications)}}. + + + + + + + Extended tyoe for A reference to the creator of the Specification + + + + + + + + + + A reference to the creator of the Specification + + + + + + + The manufacturer of a piece of equipment or component. + + + + + + + The owner or implementer of a piece of equipment or component. + + + + + + + + + A reference to the creator of the Specification + + + + + + + + A specification + + + + + + The identity of the Specificaiton + + + + + + + The type of measurement + + + + + + + A reference to the creator of the Specification + + + + + + + The type of measurement + + + + + + + identifier of the maintenance activity. + + + + + + + The optional data item identifier + + + + + + + The optional composition identifier + + + + + + + The optional coordinate system identifier + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + + A specification + + + + + + + design characteristics for a piece of equipment. + + + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + upper conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + upper boundary indicating increased concern and supervision may + be required. + + + + + + + lower boundary indicating increased concern and supervision may + be required. + + + + + + + lower conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + + + + + design characteristics for a piece of equipment. + + + + + + + The limit of a constraint + + + + + + + + + + The limit of a constraint + + + + + + + numeric upper constraint. + + + + + + + + + + numeric upper constraint. + + + + + + + numeric lower constraint. + + + + + + + + + + numeric lower constraint. + + + + + + + numeric target or expected value. + + + + + + + + + + numeric target or expected value. + + + + + + + upper conformance boundary for a variable. > Note: immediate concern + or action may be required. + + + + + + + + + + upper conformance boundary for a variable. > Note: immediate concern + or action may be required. + + + + + + + upper boundary indicating increased concern and supervision may be + required. + + + + + + + + + + upper boundary indicating increased concern and supervision may be + required. + + + + + + + lower boundary indicating increased concern and supervision may be + required. + + + + + + + + + + lower boundary indicating increased concern and supervision may be + required. + + + + + + + lower conformance boundary for a variable. > Note: immediate concern + or action may be required. + + + + + + + + + + lower conformance boundary for a variable. > Note: immediate concern + or action may be required. + + + + + + + {{block(Specification)}} that provides information used to assess the + conformance of a variable to process requirements. + + + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + + + + + {{block(Specification)}} that provides information used to assess the + conformance of a variable to process requirements. + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + upper conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + upper boundary indicating increased concern and supervision may be + required. + + + + + + + numeric target or expected value. + + + + + + + lower boundary indicating increased concern and supervision may be + required. + + + + + + + lower conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + upper conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + upper boundary indicating increased concern and supervision may be + required. + + + + + + + lower boundary indicating increased concern and supervision may be + required. + + + + + + + lower conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + upper conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + numeric target or expected value. + + + + + + + lower conformance boundary for a variable. > Note: immediate + concern or action may be required. + + + + + + + + + {{block(Relationships)}} groups one or more + {{block(ConfigurationRelationship)}} types. See + {{package(Relationships)}}. + + + + + + + + + + + + + + {{block(Relationships)}} groups one or more + {{block(ConfigurationRelationship)}} types. See + {{package(Relationships)}}. + + + + + + + The list of possible association types + + + + + + + The related entity is a parent + + + + + + + The related entity is a child + + + + + + + The related entity is a peer + + + + + + + + + device relationships + + + + + + + a system + + + + + + + an auxiliary + + + + + + + + + The criticality + + + + + + + critical + + + + + + + Not critical + + + + + + + + + A relationship between this component and something else + + + + + + The relationship identifier + + + + + + + identifier of the maintenance activity. + + + + + + + The assciation type + + + + + + + Criticality + + + + + + + + A relationship between this component and something else + + + + + + + {{block(ConfigurationRelationship)}} that describes the association + between two components within a piece of equipment that function + independently but together perform a capability or service within a + piece of equipment. + + + + + + + + A reference to the device uuid + + + + + + + + + + {{block(ConfigurationRelationship)}} that describes the association + between two components within a piece of equipment that function + independently but together perform a capability or service within a + piece of equipment. + + + + + + + {{block(ConfigurationRelationship)}} that describes the association + between two pieces of equipment that function independently but together + perform a manufacturing operation. + + + + + + + + A reference to the device uuid + + + + + + + The type of relatiship + + + + + + + {{term(URL)}} giving the location of the image file. + + + + + + + Description + + + + + + + + + + {{block(ConfigurationRelationship)}} that describes the association + between two pieces of equipment that function independently but together + perform a manufacturing operation. + + + + + + + The type of coordinate system + + + + + + + The world + + + + + + + The base of the manipulator chain + + + + + + + The object + + + + + + + The current task + + + + + + + The last joint in the chain + + + + + + + The tool's coord + + + + + + + The platform + + + + + + + For machine tools, the coordinate system in the work area + + + + + + + For machine tools, the coordinate system in the work area + + + + + + + + + {{block(CoordinateSystems)}} groups one or more + {{block(CoordinateSystem)}} entities. See + {{package(CoordinateSystems)}}. + + + + + + + + + Description + + + + + + + + + + + {{block(CoordinateSystems)}} groups one or more + {{block(CoordinateSystem)}} entities. See + {{package(CoordinateSystems)}}. + + + + + + + Description + + + + + + + See {{sect(Origin)}}. + + + + + + + The location (no parent) as DataSet + + + + + + + See {{sect(Transformation)}}. + + + + + + + + The coordinate system identifier + + + + + + + identifier of the maintenance activity. + + + + + + + The optional name of the coordinate system + + + + + + + The parent of the coordinate system + + + + + + + The coordinate system type + + + + + + + uuid + + + + + + + + See {{sect(Origin)}}. + + + + + + + + + + See {{sect(Transformation)}}. + + + + + + + + translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + An offset applied first + + + + + + + + + rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + A quaternion transform applied second + + + + + + + + + + The types of motion + + + + + + + Rotates around an axis with a fixed range of motion + + + + + + + Revolves around an axis with a continuous range of motion + + + + + + + Sliding linear motion along an axis with a fixed range of motion + + + + + + + The axis does not move. + + + + + + + + + The actuation of this component + + + + + + + The movement is initiated by the component. + + + + + + + The motion is computed and is used for expressing an imaginary + movement. + + + + + + + There is no actuation of this Axis. + + + + + + + + + The unit vector along which the motion occurs + + + + + + + + + + The description of the motion + + + + + + + Any elements + + + + + + + + + See {{sect(Motion)}}. + + + + + + + + + See {{sect(Description)}}. + + + + + + + + The location (no parent) + + + + + + + See {{sect(Origin)}}. + + + + + + + See {{sect(Transformation)}}. + + + + + + + + + The axis motion + + + + + + + See {{sect(Axis)}}. + + + + + + + + + The coordinate system identifier + + + + + + + The parent of the coordinate system + + + + + + + The identifier of the coordinate system that this motion is + relative to + + + + + + + The motion type + + + + + + + The actuation method + + + + + + + + + + See {{sect(Motion)}}. + + + + + + + A reference to another model + + + + + + + + A reference to an item in a model + + + + + + + + A three dimensional value 'X Y Z' or 'A B C' + + + + + + + + + + + The unit vector to scale the model + + + + + + + + + + See {{sect(SolidModel)}}. + + + + + + + + + See {{sect(Transformation)}}. + + + + + + + + See {{sect(Scale)}}. + + + + + + + Scaling vector for the model + + + + + + + + + the unique identifier for this entity within the MTConnectDevices + document + + + + + + + The associated model file if an item reference is used + + + + + + + {{term(URL)}} giving the location of the image file. + + + + + + + Description + + + + + + + The reference to the item within the model within the related + geometry. A modelIdRef MUST be given. + + + + + + + The format of the referenced document + + + + + + + The identifier of the coordinate system that this motion is + relative to + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + The units as expressed by the machine + + + + + + + + + + See {{sect(SolidModel)}}. + + + + + + + Extended tyoe for Solid model media types + + + + + + + + + + Solid model media types + + + + + + + ISO 10303 STEP AP203 or AP242 format + + + + + + + Stereolithography file format + + + + + + + Geometry Description Markup Language + + + + + + + Wavefront OBJ file format + + + + + + + ISO 17506 + + + + + + + Initial Graphics Exchange Specification + + + + + + + Autodesk file format + + + + + + + Dassault file format + + + + + + + Parasolid XT Siemens data interchange format + + + + + + + + + Solid model media types + + + + + + + + url of an image file + + + + + + + + mime type + + + + + + + + This section provides semantic information for the {{block(ImageFile)}} + entity. + + + + + + + + + reference to a file containing an image of the + {{block(Component)}}. + + + + + + + + + + + This section provides semantic information for the {{block(ImageFile)}} + entity. + + + + + + + reference to a file containing an image of the {{block(Component)}}. + + + + + + + + identifier + + + + + + + identifier of the maintenance activity. + + + + + + + URL of image file + + + + + + + mime type of image file + + + + + + + + + + The item's reference to the component + + + + + + + + The name of the power source + + + + + + + + The order of precedence for a given power source + + + + + + + + The type of power source + + + + + + + main or principle + + + + + + + alternate or not primary + + + + + + + held near at hand and ready for use and is uninterruptible + + + + + + + + + This section provides semantic information for the + {{block(PowerSource)}} entity. ![PowerSources](figures/PowerSources.png + "PowerSources"){: width="0.8"} + + + + + + + + + potential energy sources for the {{block(Component)}}. + + + + + + + + + + + This section provides semantic information for the + {{block(PowerSource)}} entity. ![PowerSources](figures/PowerSources.png + "PowerSources"){: width="0.8"} + + + + + + + potential energy sources for the {{block(Component)}}. + + + + + + + optional precedence for a given power source + + + + + + + single data value that is expected to be reported for a + {{block(DataItem)}}. {{property(Constraints::Value)}} **MUST NOT** + be used in conjunction with any other {{block(Constraint)}} + elements. + + + + + + + + type of power source + + + + + + + identifier + + + + + + + reference to component + + + + + + + + The interval between adjacent sampleing of data + + + + + + + + The frequency a measurement is sampled + + + + + + + + The constrained value for this data item + + + + + + + + The constrained value for this data item + + + + + + + + The constrained value for this data item + + + + + + + + An idref to the component id + + + + + + + + An idref to the data item id + + + + + + + + The item's reference to the data item or specificatiton + + + + + + + + The name of a related component + + + + + + + + The id reference for the coordinate system associated with this data + item + + + + + + + + An discrete event + + + + + + + + The description of a data item, can be free form text or elements + + + + + + + Any elements + + + + + + + + + The minimum limit on the change in a value + + + + + + + + The measurement sampling type + + + + + + + An event represents a change in state occurs at a point in time. + Note: An event does not occur at predefined frequencies. + + + + + + + A sample is a data point for continuous data items, that is, the + value of a data item at a point in time. + + + + + + + The condition of the device + + + + + + + + + The multiplier for the native value. Conversion divides by this value + + + + + + + + Description + + + + + + + series of sampled data. The data is reported for a specified number + of samples and each sample is reported with a fixed period. + + + + + + + measured value of the sample data. If no + {{property(DataItem::representation)}} is specified for a data item, + the {{property(DataItem::representation)}} **MUST** be determined to + be `VALUE`. + + + + + + + reported value(s) are represented as a set of {{termplural(key-value + pair)}}. Each reported value in the {{term(data set)}} **MUST** have + a unique key. + + + + + + + **DEPRECATED** as {{property(DataItem::representation)}} type in + *MTConnect Version 1.5*. Replaced by the + {{property(DataItem::discrete)}}. + + + + + + + two dimensional set of {{termplural(key-value pair)}} where the + {{block(Entry)}} represents a row, and the value is a set of + {{term(key-value pair)}} {{block(Cell)}} elements. A {{term(table)}} + follows the same behavior as the {{term(data set)}} for change + tracking, clearing, and history. When an {{block(Entry)}} changes, + all {{block(Cell)}} elements update as a single unit following the + behavior of a {{term(data set)}}. > Note: It is best to use + {{block(Variable)}} if the {{block(Cell)}} entities represent + multiple semantic types. Each {{block(Entry)}} in the + {{term(table)}} **MUST** have a unique key. Each {{block(Cell)}} of + each {{block(Entry)}} in the {{term(table)}} **MUST** have a unique + key. See {{block(Representation)}} in {{package(Observation + Information Model)}}, for a description of {{block(Entry)}} and + {{block(Cell)}} elements. + + + + + + + + + The type of filter + + + + + + + new value **MUST NOT** be reported for a data item unless the + measured value has changed from the last reported value by at least + the delta given as the value of this element. The value of + {{block(Filter)}} **MUST** be an absolute value using the same units + as the reported data. + + + + + + + data reported for a data item is provided on a periodic basis. The + `PERIOD` for reporting data is defined in the value of the + {{block(Filter)}}. The value of {{block(Filter)}} **MUST** be an + absolute value reported in seconds representing the time between + reported samples of the value of the data item. + + + + + + + + + + + + + + information reported about a piece of equipment. + + + + + + + + + information reported about a piece of equipment. + + + + + + + identifies the {{block(Component)}}, {{block(DataItem)}}, or + {{block(Composition)}} from which a measured value originates. + + + + + + + {{termplural(organize)}} a set of expected values that can be + reported for a {{block(DataItem)}}. + + + + + + + {{block(Filters)}} groups one or more {{block(Filter)}} entities + associated with the {{block(DataItem)}}. + + + + + + + starting value for a {{block(DataItem)}} as well as the value to be + set for the {{block(DataItem)}} after a reset event. + + + + + + + type of event that may cause a reset to occur. + + + + + + + defines the meaning of {{block(Entry)}} and {{block(Cell)}} entities + when the associated {{property(DataItem::representation)}} is either + `DATA_SET` or `TABLE`. + + + + + + + {{block(Relationships)}} groups one or more + {{block(ConfigurationRelationship)}} types. See + {{package(Relationships)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + unique identifier for the power source. + + + + + + + The type of measurement + + + + + + + The sub type for the measurement + + + + + + + The statistical operation on this data + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + The units as expressed by the machine + + + + + + + The units as expressed by the machine + + + + + + + The category of the data item + + + + + + + Description + + + + + + + The coordinate system reference to a particular coordinate system + + + + + + + The optional composition identifier + + + + + + + Used as the default sample rate for waveforms + + + + + + + Description + + + + + + + The number of significant digits for this data item + + + + + + + Description + + + + + + + + A set of limits for a data item + + + + + + + + + single data value that is expected to be reported for a + {{block(DataItem)}}. {{property(Constraints::Value)}} **MUST + NOT** be used in conjunction with any other + {{block(Constraint)}} elements. + + + + + + + + + numeric lower constraint. + + + + + + + numeric upper constraint. + + + + + + + numeric target or expected value. + + + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + + + {{block(Filters)}} groups one or more {{block(Filter)}} entities + associated with the {{block(DataItem)}}. + + + + + + + **DEPRECATED** in *MTConnect Version 1.4*. Moved to the + {{block(Filters)}}. See {{package(Properties of DataItem)}}. + + + + + + + + + A starting point for a data item + + + + + + + + + + The value element + + + + + + + + + + The filter for the data item + + + + + + + + The type of filter, ABSOLUTE or PERCENT + + + + + + + + + + A native data source + + + + + + + + The optional data item within the source component that provides + the underlying data + + + + + + + The component that is collecting the data associated with this + data item + + + + + + + The optional composition identifier for the source of this data + item + + + + + + + + + + The DataItem Definition + + + + + + + See {{sect(Description)}}. + + + + + + + {{block(EntryDefinitions)}} groups one or more + {{block(EntryDefinition)}} entities. See {{sect(EntryDefinition)}}. + + + + + + + {{block(CellDefinitions)}} groups one or more + {{block(CellDefinition)}} entities. See {{sect(CellDefinition)}}. + + + + + + + + + {{block(EntryDefinitions)}} groups one or more + {{block(EntryDefinition)}} entities. See {{sect(EntryDefinition)}}. + + + + + + + semantic definition of an {{block(Entry)}}. + + + + + + + + + + unique key + + + + + + + The type of measurement + + + + + + + The type of measurement + + + + + + + The sub type for the measurement + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device + Information Model)}}. + + + + + + + + semantic definition of an {{block(Entry)}}. + + + + + + + See {{sect(Description)}}. + + + + + + + {{block(CellDefinitions)}} groups one or more + {{block(CellDefinition)}} entities. See {{sect(CellDefinition)}}. + + + + + + + + + + {{block(CellDefinitions)}} groups one or more {{block(CellDefinition)}} + entities. See {{sect(CellDefinition)}}. + + + + + + + semantic definition of a {{block(Cell)}}. + + + + + + + + + semantic definition of a {{block(Cell)}}. + + + + + + + See {{sect(Description)}}. + + + + + + + + + + Organizes DataItemRelationship and SpecificationRelationship + + + + + + + + + + Description + + + + + + identifier of the maintenance activity. + + + + + + + A reference to the related DataItem id. + + + + + + + + Description + + + + + + + How the data items are related + + + + + + + A reference to a DataItem that associates the values with an + external entity + + + + + + + The referenced DataItem provides the id of the effective Coordinate + System + + + + + + + The referenced DataItem provides process limits. + + + + + + + The referenced DataItem provides the observed values. + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(DataItem)}} described by + {{property(DataItemRelationship::type)}}. + + + + + + + + type of the power source. + + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(DataItem)}} described by + {{property(DataItemRelationship::type)}}. + + + + + + + How the data items are related + + + + + + + The referenced DataItem provides process limits. + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(Specification)}} described by + {{property(SpecificationRelationship::type)}} and + {{property(SpecificationRelationship::idRef)}}. + + + + + + + + type of the power source. + + + + + + + + + + {{block(AbstractDataItemRelationship)}} that provides a semantic + reference to another {{block(Specification)}} described by + {{property(SpecificationRelationship::type)}} and + {{property(SpecificationRelationship::idRef)}}. + + + + \ No newline at end of file diff --git a/schemas/MTConnectError_2.5.xsd b/schemas/MTConnectError_2.5.xsd new file mode 100644 index 000000000..de131d2a5 --- /dev/null +++ b/schemas/MTConnectError_2.5.xsd @@ -0,0 +1,4667 @@ + + + + + + + root entity of an {{term(MTConnectErrors Response Document)}} that + contains the {{term(Error Information Model)}}. + ![MTConnectError](figures/MTConnectErrors.png + "MTConnectError"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectError)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + The sender of the message + + + + + + + + The date and time the document was created + + + + + + + + A sequence number + + + + + + + + + + + A debugging flag for testing. + + + + + + + + The instance number of the agent, used for fault tolerance + + + + + + + + + + + The size of the agents buffer + + + + + + + + + + + The time the sample was reported + + + + + + + + The time a sample occurred + + + + + + + + A version number + + + + + + + + A short name for any element + + + + + + + + A universally unique id that uniquely identifies the element for + it's entire life + + + + + + + + A serial number for a piece of equipment + + + + + + + + The measurement source + + + + + + + + A sample rate in milliseconds per sample + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + + An identifier + + + + + + + + The number significant digits + + + + + + + + The item's reference to the Device model composition + + + + + + + + A length of time in seconds + + + + + + + + A flag indicating the item has been removed + + + + + + + + The key for adata set + + + + + + + + A timestamp in 8601 format of the last update of the Device information + for any device + + + + + + + + The unique id of the asset + + + + + + + + An asset type + + + + + + + + The maximum number of assets + + + + + + + + + + + The number of assets + + + + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + The limit of a value + + + + + + + + Common floating point sample value + + + + + + + + + + + + A three dimensional value 'X Y Z' or 'A B C' + + + + + + + + + + + A description + + + + + + + + Extended tyoe for The types of measurements available + + + + + + + + + + The types of measurements available + + + + + + + positive rate of change of velocity. + + + + + + + accumulated time for an activity or event. + + + + + + + strength of electrical current. **DEPRECATED** in *Version 1.6*. + Replaced by `AMPERAGE_AC` and `AMPERAGE_DC`. + + + + + + + angular position. + + + + + + + positive rate of change of angular velocity. + + + + + + + rate of change of angular position. + + + + + + + feedrate of a linear axis. + + + + + + + fluid capacity of an object or container. + + + + + + + geometric capacity of an object or container. + + + + + + + percentage of one component within a mixture of components. + + + + + + + ability of a material to conduct electricity. + + + + + + + speed difference (relative velocity) between the cutting mechanism + and the surface of the workpiece it is operating on. + + + + + + + volumetric mass of a material per unit volume of that material. + + + + + + + rate of change in spatial volume of material deposited in an + additive manufacturing process. + + + + + + + density of the material deposited in an additive manufacturing + process per unit of volume. + + + + + + + mass of the material deposited in an additive manufacturing process. + + + + + + + rate at which a spatial volume of material is deposited in an + additive manufacturing process. + + + + + + + spatial volume of material to be deposited in an additive + manufacturing process. + + + + + + + change in position of an object. + + + + + + + {{block(Wattage)}} used or generated by a component over an interval + of time. + + + + + + + amount of time a piece of equipment or a sub-part of a piece of + equipment has performed specific activities. + + + + + + + amount of a substance remaining compared to the planned maximum + amount of that substance. + + + + + + + rate of flow of a fluid. + + + + + + + number of occurrences of a repeating event per unit time. + + + + + + + position in three-dimensional space. **DEPRECATED** in Version 1.1. + + + + + + + length of an object. + + + + + + + level of a resource. **DEPRECATED** in *Version 1.2*. See + `FILL_LEVEL`. + + + + + + + {{term(force)}} applied to a mass in one direction only. + + + + + + + actual versus the standard rating of a piece of equipment. + + + + + + + mass of an object(s) or an amount of material. + + + + + + + feedrate for the axes, or a single axis, associated with a + {{block(Path)}} component. + + + + + + + feedrate for the axes, or a single axis. + + + + + + + position of a control point associated with a {{block(Controller)}} + or a {{block(Path)}}. + + + + + + + acidity or alkalinity of a solution. + + + + + + + point along an axis in a {{term(cartesian coordinate system)}}. + + + + + + + ratio of real power flowing to a load to the apparent power in that + AC circuit. + + + + + + + force per unit area measured relative to atmospheric pressure. + Commonly referred to as gauge pressure. + + + + + + + amount of time a piece of equipment has performed different types of + activities associated with the process being performed at that piece + of equipment. + + + + + + + degree to which a substance opposes the passage of an electric + current. + + + + + + + rotational speed of a rotary axis. + + + + + + + sound level or sound pressure level relative to atmospheric + pressure. + + + + + + + rotational speed of the rotary axis. **DEPRECATED** in *Version + 1.2*. Replaced by `ROTARY_VELOCITY`. + + + + + + + amount of deformation per unit length of an object when a load is + applied. + + + + + + + degree of hotness or coldness measured on a definite scale. + + + + + + + force that stretches or elongates an object. + + + + + + + angular displacement. + + + + + + + turning force exerted on an object or by an object. + + + + + + + rate of change of position of a {{block(Component)}}. + + + + + + + fluid's resistance to flow. + + + + + + + electrical potential between two points. **DEPRECATED** in *Version + 1.6*. Replaced by `VOLTAGE_AC` and `VOLTAGE_DC`. + + + + + + + apparent power in an electrical circuit, equal to the product of + root-mean-square (RMS) voltage and RMS current (commonly referred to + as VA). + + + + + + + reactive power in an AC electrical circuit (commonly referred to as + VAR). + + + + + + + fluid volume of an object or container. + + + + + + + geometric volume of an object or container. + + + + + + + power flowing through or dissipated by an electrical circuit or + piece of equipment. + + + + + + + electrical current that reverses direction at regular short + intervals. + + + + + + + electric current flowing in one direction only. + + + + + + + electrical potential between two points in an electrical circuit in + which the current periodically reverses direction. + + + + + + + electrical potential between two points in an electrical circuit in + which the current is unidirectional. + + + + + + + dimension of an entity relative to the X direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Y direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Z direction of the referenced + coordinate system. + + + + + + + dimension of a diameter. + + + + + + + angular position of a plane or vector relative to a {{term(cartesian + coordinate system)}} + + + + + + + amount of water vapor present expressed as a percent to reach + saturation at the same temperature. + + + + + + + amount of water vapor expressed in grams per cubic meter. + + + + + + + ratio of the water vapor present over the total weight of the water + vapor and air present expressed as a percent. + + + + + + + average rate of change of values for data items in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + average rate of change of values for assets in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + change of pressure per unit time. + + + + + + + negative rate of change of velocity. + + + + + + + negative rate of change of angular velocity. + + + + + + + force per unit area measured relative to a vacuum. + + + + + + + percentage open where 100% is fully open and 0% is fully closed. + + + + + + + temperature at which moisture begins to condense, corresponding to + saturation for a given absolute humidity. + + + + + + + force relative to earth's gravity. + + + + + + + acceleration relative to Earth's gravity of 9.80665 + `METER/SECOND^2`. + + + + + + + maximum rated charge a battery is capable of maintaining based on + the battery discharging at a specified current over a specified time + period. + + + + + + + value of current being drawn from the {{block(Component)}}. + + + + + + + value of the current being supplied to the {{block(Component)}} for + the purpose of charging. + + + + + + + value of the battery's present capacity expressed as a + percentage of the battery's maximum rated capacity. + + + + + + + difference between actual and commanded position at the end of a + motion. + + + + + + + difference between actual and commanded position at any specific + point in time during a motion. + + + + + + + difference between the commanded encoder/resolver position, and the + actual encoder/resolver position when motion is complete. + + + + + + + angular difference between the commanded encoder/resolver position, + and the actual encoder/resolver position when motion is complete. + + + + + + + difference between the commanded encoder/resolver position and the + actual encoder/resolver position at any specified point in time + during a motion. + + + + + + + angular difference between the commanded encoder/resolver position + and the actual encoder/resolver position at any specified point in + time during a motion. + + + + + + + absolute value of the change in position along a vector. + + + + + + + absolute value of the change in angular position around a vector + + + + + + + point in a {{term(cartesian coordinate system)}}. + + + + + + + set of axes currently associated with a {{block(Path)}} or + {{block(Controller)}}. + + + + + + + operational state of an apparatus for moving or controlling a + mechanism or system. + + + + + + + **DEPRECATED:** Replaced with `CONDITION` category data items in + Version 1.1.0. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been added or + changed. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been removed. + + + + + + + {{term(agent)}}'s ability to communicate with the data source. + + + + + + + describes the way the axes will be associated to each other. This is + used in conjunction with `COUPLED_AXES` to indicate the way they are + interacting. + + + + + + + value of a signal or calculation issued to adjust the feedrate of an + individual linear type axis. + + + + + + + state of the axis lockout function when power has been removed and + the axis is allowed to move freely. + + + + + + + state of a {{block(Linear)}} or {{block(Rotary)}} component + representing an axis. + + + + + + + line of code or command being executed by a {{block(Controller)}} + entity. + + + + + + + total count of the number of blocks of program code that have been + executed since execution started. + + + + + + + state of an interlock function or control logic state intended to + prevent the associated {{block(Chuck)}} component from being + operated. + + + + + + + operating state of a mechanism that holds a part or stock material + during a manufacturing process. It may also represent a mechanism + that holds any other mechanism in place within a piece of equipment. + + + + + + + programmatic code being executed. **DEPRECATED** in *Version 1.1*. + + + + + + + operating state of a mechanism represented by a + {{block(Composition)}} entity. + + + + + + + current mode of the {{block(Controller)}} component. + + + + + + + setting or operator selection that changes the behavior of a piece + of equipment. + + + + + + + set of associated axes. + + + + + + + time and date code associated with a material or other physical + item. + + + + + + + identifier of another piece of equipment that is temporarily + associated with a component of this piece of equipment to perform a + particular function. + + + + + + + direction of motion. + + + + + + + operational state of a {{block(Door)}} component or composition + element. + + + + + + + state of the emergency stop signal for a piece of equipment, + controller path, or any other component or subsystem of a piece of + equipment. + + + + + + + indication of whether the end of a piece of bar stock being feed by + a bar feeder has been reached. + + + + + + + indication that a piece of equipment, or a sub-part of a piece of + equipment, is performing specific types of activities. + + + + + + + operating state of a {{block(Component)}}. + + + + + + + current intended production status of the {{block(Component)}}. + + + + + + + hardness of a material. + + + + + + + current line of code being executed. **DEPRECATED** in *Version + 1.4.0*. + + + + + + + identifier for a {{block(Block)}} of code in a {{block(Program)}}. + + + + + + + position of a block of program code within a control program. + + + + + + + identifier of a material used or consumed in the manufacturing + process. + + + + + + + identifies the layers of material applied to a part or product as + part of an additive manufacturing process. + + + + + + + information to be transferred from a piece of equipment to a client + software application. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + identifier for a pallet. + + + + + + + aggregate count of parts. + + + + + + + indication designating whether a part or work piece has been + detected or is present. + + + + + + + identifier of a part in a manufacturing operation. + + + + + + + identifier of a part or product moving through the manufacturing + process. **DEPRECATED** in *Version 1.7*. `PART_NUMBER` is now a + `subType` of `PART_KIND_ID`. + + + + + + + value of a signal or calculation issued to adjust the feedrate for + the axes associated with a {{block(Path)}} component that may + represent a single axis or the coordinated movement of multiple + axes. + + + + + + + describes the operational relationship between a {{block(Path)}} + entity and another {{block(Path)}} entity for pieces of equipment + comprised of multiple logical groupings of controlled axes or other + logical operations. + + + + + + + indication of the status of the source of energy for an entity to + allow it to perform its intended function or the state of an + enabling signal providing permission for the entity to perform its + functions. + + + + + + + status of the {{block(Component)}}. **DEPRECATED** in *Version + 1.1.0*. + + + + + + + time and date associated with an activity or event. + + + + + + + name of the logic or motion program being executed by the + {{block(Controller)}} component. + + + + + + + comment or non-executable statement in the control program. + + + + + + + indication of the status of the {{block(Controller)}} components + program editing mode. A program may be edited while another is + executed. + + + + + + + name of the program being edited. This is used in conjunction with + {{block(ProgramEdit)}} when in `ACTIVE` state. + + + + + + + non-executable header section of the control program. + + + + + + + {{term(URI)}} for the source file associated with + {{block(Program)}}. + + + + + + + defines whether the logic or motion program defined by + {{block(Program)}} is being executed from the local memory of the + controller or from an outside source. + + + + + + + indication of the nesting level within a control program that is + associated with the code or instructions that is currently being + executed. + + + + + + + current operating mode for a {{block(Rotary)}} type axis. + + + + + + + percentage change to the velocity of the programmed velocity for a + {{block(Rotary)}} axis. + + + + + + + serial number associated with a {{block(Component)}}, + {{block(Asset)}}, or {{block(Device)}}. + + + + + + + indication of the status of the spindle for a piece of equipment + when power has been removed and it is free to rotate. + + + + + + + identifier of an individual tool asset. + + + + + + + identifier for the tool group associated with a specific tool. + Commonly used to designate spare tools. + + + + + + + identifier of the tool currently in use for a given `Path`. + **DEPRECATED** in *Version 1.2.0*. See `TOOL_ASSET_ID`. + + + + + + + identifier assigned by the {{block(Controller)}} component to a + cutting tool when in use by a piece of equipment. + + + + + + + reference to the tool offset variables applied to the active cutting + tool. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + data whose meaning may change over time due to changes in the + operation of a piece of equipment or the process being executed on + that piece of equipment. + + + + + + + indication of the reason that {{block(Execution)}} is reporting a + value of `WAIT`. + + + + + + + identifier for the type of wire used as the cutting mechanism in + Electrical Discharge Machining or similar processes. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. **DEPRECATION WARNING**: Recommend using + `FIXTURE_ID` instead. + + + + + + + reference to offset variables for a work piece or part. + + + + + + + Operating System (OS) of a {{block(Component)}}. + + + + + + + embedded software of a {{block(Component)}} . + + + + + + + application on a {{block(Component)}}. + + + + + + + software library on a {{block(Component)}} + + + + + + + hardware of a {{block(Component)}}. + + + + + + + network details of a {{block(Component)}}. + + + + + + + three space angular displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + three space linear displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + {{term(UUID)}} of new device added to an {{term(MTConnect Agent)}}. + + + + + + + {{term(UUID)}} of a device removed from an {{term(MTConnect + Agent)}}. + + + + + + + {{term(UUID)}} of the device whose {{term(metadata)}} has changed. + + + + + + + status of the connection between an {{term(adapter)}} and an + {{term(agent)}}. + + + + + + + originator’s software version of the {{term(adapter)}}. + + + + + + + {{term(URI)}} of the {{term(adapter)}}. + + + + + + + reference version of the MTConnect Standard supported by the + {{term(adapter)}}. + + + + + + + {{term(attachment)}} between a sensor and an entity. + + + + + + + state or condition of a part. + + + + + + + identifier of a process being executed by the device. + + + + + + + identifier given to link the individual occurrence to a group of + related occurrences, such as a process step in a process plan. + + + + + + + identifier given to link the individual occurrence to a class of + processes or process definition. + + + + + + + identifier given to a collection of individual parts. + + + + + + + identifier given to link the individual occurrence to a class of + parts, typically distinguished by a particular part design. + + + + + + + identifier given to a distinguishable, individual part. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. **DEPRECATION WARNING**. Recommend using + `CONTROL_LIMITS`. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. **DEPRECATION WARNING**. Recommend using + `SPECIFICATION_LIMITS`. + + + + + + + set of limits used to trigger warning or alarm indicators. + **DEPRECATION WARNING**. Recommend using `ALARM_LIMITS`. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, load materials, parts, or other items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, unload materials, parts, or other + items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, transfer materials, parts, or other + items from one location to another. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, activate or be performed. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, deactivate or cease. + + + + + + + accumulation of the number of times a cyclic function has attempted + to, or is planned to attempt to execute. + + + + + + + state of a valve is one of open, closed, or transitioning between + the states. + + + + + + + state or operating mode of a {{block(Lock)}}. + + + + + + + particular condition of the process occurrence at a specific time. + + + + + + + particular condition of the part occurrence at a specific time. + + + + + + + state of {{block(Component)}} or {{block(Composition)}} that + describes the automatic or manual operation of the entity. + + + + + + + {{term(data set)}} of the number of {{termplural(Asset)}} of a given + type for a {{term(Device)}}. + + + + + + + actions or activities to be performed in support of a piece of + equipment. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. + + + + + + + interpretation of `PART_COUNT`. + + + + + + + time provided by a timing device at a specific point in time. + + + + + + + name of the host computer supplying data. + + + + + + + number of the TCP/IP or UDP/IP port for the connection endpoint. + + + + + + + indication designating whether a leak has been detected. + + + + + + + present status of the battery. + + + + + + + {{term(UUID)}} of a {{term(feature)}}. {{cite(ISO 10303 AP + 242/239)}}. + + + + + + + detection result of a sensor. + + + + + + + {{block(Event)}} that represents a {{block(Component)}} where the + {{block(EntryDefinition)}} identifies the {{block(Component)}} and + the {{block(CellDefinition)}}s define the + {{block(Component)}}'s observed {{block(DataItem)}}s. + + + + + + + properties of each addressable work offset. + + + + + + + properties of each addressable tool offset. + + + + + + + assessing elements of a {{term(feature)}}. + + + + + + + {{term(UUID)}} of the {{term(characteristic)}}. + + + + + + + class of measurement being performed. {{cite(QIF 3:2018 Section + 6.3)}} + + + + + + + measurement based on the measurement type. + + + + + + + engineering units of the measurement. + + + + + + + pass/fail result of the measurement. + + + + + + + method used to compute {{term(standard uncertainty)}}. + + + + + + + {{term(uncertainty)}} specified by {{block(UncertaintyType)}}. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. + + + + + + + set of limits used to trigger warning or alarm indicators. + + + + + + + references the {{block(CuttingToolLifeCycle)}} + {{block(CuttingItem)}} index related to the + {{property(CuttingItem::indices)}} of the currently active cutting + tool edge. + + + + + + + structured information that allows the unambiguous determination of + an object for purposes of identification and location. {{cite(ISO + 19160-4:2017)}} + + + + + + + active energy source for the {{block(Component)}}. + + + + + + + textual description of the location of an object or activity. + + + + + + + dimension between two surfaces of an object, usually the dimension + of smallest measure, for example an additive layer, or a depth of + cut. + + + + + + + absolute geographic location defined by two coordinates, longitude + and latitude and an elevation. + + + + + + + indication that the piece of equipment has experienced a + communications failure. + + + + + + + indication that the value of the data associated with a measured + value or a calculation is outside of an expected range. + + + + + + + indication that an error occurred in the logic program or + programmable logic controller (PLC) associated with a piece of + equipment. + + + + + + + indication that an error occurred in the motion program associated + with a piece of equipment. + + + + + + + general purpose indication associated with an electronic component + of a piece of equipment or a controller that represents a fault that + is not associated with the operator, program, or hardware. + + + + + + + indication of a fault associated with an actuator. + + + + + + + operational state of an {{block(Interface)}}. + + + + + + + operating state of the service to advance material or feed product + to a piece of equipment from a continuous or bulk source. + + + + + + + operating state of the service to change the type of material or + product being loaded or fed to a piece of equipment. + + + + + + + operating state of the service to remove or retract material or + product. + + + + + + + operating state of the service to change the part or product + associated with a piece of equipment to a different part or product. + + + + + + + operating state of the service to load a piece of material or + product. + + + + + + + operating state of the service to unload a piece of material or + product. + + + + + + + operating state of the service to open a chuck. + + + + + + + operating state of the service to open a door. + + + + + + + operating state of the service to close a chuck. + + + + + + + operating state of the service to close a door. + + + + + + + A user variable + + + + + + + + + The types of measurements available + + + + + + + + Extended tyoe for The sub-types for a measurement + + + + + + + + + + The sub-types for a measurement + + + + + + + relating to or derived in the simplest manner from the fundamental + units or measurements. + + + + + + + indication of the operating state of a mechanism. + + + + + + + measured or reported value of an {{term(observation)}}. + + + + + + + all actions, items, or activities being counted independent of the + outcome. + + + + + + + measurement of alternating voltage or current. If not specified + further in statistic, defaults to RMS voltage. **DEPRECATED** in + *Version 1.6*. + + + + + + + A-Scale weighting factor on the frequency scale. + + + + + + + when multiple locations on a piece of bar stock being feed by a bar + feeder are referenced as the indication of whether the end of that + piece of bar stock has been reached. + + + + + + + actions, items, or activities being counted that do not conform to + specification or expectation. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + B-Scale weighting factor on the frequency scale. + + + + + + + directive value including adjustments such as an offset or + overrides. + + + + + + + amount of material consumed from an object or container during a + manufacturing process. + + + + + + + state of the enabling signal or control logic that enables or + disables the function or operation of the entity. + + + + + + + C-Scale weighting factor on the frequency scale. + + + + + + + elapsed time of a temporary halt of action. + + + + + + + DC current or voltage. **DEPRECATED** in *Version 1.6*. + + + + + + + setting or operator selection used to execute a test mode to confirm + the execution of machine functions. + + + + + + + D-Scale weighting factor on the frequency scale. + + + + + + + relating to the expiration or end of useful life for a material or + other physical item. + + + + + + + relating to the first use of a material or other physical item. + + + + + + + actions, items, or activities being counted that conform to + specification or expectation. + + + + + + + relating to or derived from the last {{term(observation)}}. + + + + + + + relating to momentary activation of a function or a movement. + **DEPRECATION WARNING**: May be deprecated in the future. + + + + + + + indication of the position of a mechanism that may move in a lateral + direction. + + + + + + + scale to measure the elasticity of a surface. + + + + + + + reference to a length type tool offset variable. + + + + + + + state of the power source. + + + + + + + direction of motion of a linear motion. + + + + + + + indication that the subparts of a piece of equipment are under load. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + relating to the primary logic or motion program currently being + executed. + + + + + + + relating to maintenance on the piece of equipment. + + + + + + + indication of the state of an operator controlled interlock that can + inhibit the ability to initiate an unclamp action of an + electronically controlled chuck. + + + + + + + related to the production of a material or other physical item. + + + + + + + maximum value. + + + + + + + minimum value. + + + + + + + scale to measure the resistance to scratching of a surface. + + + + + + + indication of the open or closed state of a mechanism. + + + + + + + no weighting factor on the frequency scale. + + + + + + + piece of equipment that is powered or performing any activity. + + + + + + + relating to the person currently responsible for operating the piece + of equipment. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + overridden value. + + + + + + + piece of equipment is powered and functioning or + {{block(Component)}} that are required to remain on are powered. + + + + + + + main or principle. + + + + + + + position provided by a measurement probe. **DEPRECATION WARNING**: + May be deprecated in the future. + + + + + + + relating to production of a part or product on a piece of equipment. + + + + + + + directive value without offsets and adjustments. + + + + + + + reference to a radial type tool offset variable. + + + + + + + performing an operation faster or in less time than nominal rate. + + + + + + + remaining measure or count of an action, object or activity. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + direction of a rotary motion using the right hand rule convention. + + + + + + + identity of a control program that is used to specify the order of + execution of other programs. + + + + + + + relating to the preparation of a piece of equipment for production + or restoring the piece of equipment to a neutral state after + production. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + standard measure of an object or an action. + + + + + + + boundary when an activity or an event commences. + + + + + + + indication of the activation state of a mechanism represented by a + {{block(Composition)}}. + + + + + + + goal of the operation or process. + + + + + + + relating to the end or completion of an activity or event. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + remaining usable measure of an object or action. + + + + + + + indication of the position of a mechanism that may move in a + vertical direction. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + piece of equipment performing any activity, the equipment is active + and performing a function under load or not. + + + + + + + IPV4 network address of the {{block(Component)}}. + + + + + + + IPV6 network address of the {{block(Component)}}. + + + + + + + Gateway for the {{block(Component)}} network. + + + + + + + SubNet mask for the {{block(Component)}} network. + + + + + + + layer2 Virtual Local Network (VLAN) ID for the {{block(Component)}} + network. + + + + + + + Media Access Control Address. The unique physical address of the + network hardware. + + + + + + + identifies whether the connection type is wireless. + + + + + + + license code to validate or activate the hardware or software. + + + + + + + version of the hardware or software. + + + + + + + date the hardware or software was released for general use. + + + + + + + date the hardware or software was installed. + + + + + + + corporate identity for the maker of the hardware or software. + + + + + + + universally unique identifier as specified in ISO 11578 or RFC 4122. + + + + + + + serial number that uniquely identifies a specific part. + + + + + + + material that is used to produce parts. + + + + + + + group of parts tracked as a lot. + + + + + + + group of parts produced in a batch. + + + + + + + material heat number. + + + + + + + particular part design or model. + + + + + + + group of parts having similarities in geometry, manufacturing + process, and/or functions. + + + + + + + word or set of words by which a part is known, addressed, or + referred to. + + + + + + + step in the process plan that this occurrence corresponds to. + + + + + + + process plan that a process occurrence belongs to. + + + + + + + authorization of a process occurrence. + + + + + + + word or set of words by which a process being executed (process + occurrence) by the device is known, addressed, or referred to. + + + + + + + reference to a ISO 10303 Executable. + + + + + + + associated with the completion of an activity or event. + + + + + + + relating to logic or motion program currently executing. + + + + + + + actions or activities that were attempted , but failed to complete + or resulted in an unexpected or unacceptable outcome. + + + + + + + actions or activities that were attempted, but terminated before + they could be completed. + + + + + + + boundary when an activity or an event terminates. + + + + + + + amount discarded. + + + + + + + amount included in the {{term(part)}}. + + + + + + + {{term(request)}} by an {{block(Interface)}} for a task. + + + + + + + {{term(response)}} by an {{block(Interface)}} to a {{term(request)}} + for a task. + + + + + + + phase or segment of a recipe or program. + + + + + + + phase of a recipe process. + + + + + + + process as part of product production; can be a subprocess of a + larger process. + + + + + + + step of a discrete manufacturing process. + + + + + + + observed as a binary data type. + + + + + + + observed as a boolean data type. + + + + + + + observed as a set containing a restricted number of discrete values + where each discrete value is named and unique. {{cite(ISO + 21961:2003, 013)}} + + + + + + + indicated by the presence or existence of something. + + + + + + + model info of the hardware or software. + + + + + + + + + The sub-types for a measurement + + + + + + + + Extended tyoe for Statistical operations on data + + + + + + + + + + Statistical operations on data + + + + + + + mathematical average value calculated for the data item during the + calculation period. + + + + + + + **DEPRECATED** in *Version 1.6*. ~~A measure of the + "peakedness" of a probability distribution; i.e., the + shape of the distribution curve.~~ + + + + + + + maximum or peak value recorded for the data item during the + calculation period. + + + + + + + middle number of a series of numbers. + + + + + + + minimum value recorded for the data item during the calculation + period. + + + + + + + number in a series of numbers that occurs most often. + + + + + + + difference between the maximum and minimum value of a data item + during the calculation period. Also represents Peak-to-Peak + measurement in a waveform. + + + + + + + mathematical Root Mean Square (RMS) value calculated for the data + item during the calculation period. + + + + + + + statistical Standard Deviation value calculated for the data item + during the calculation period. + + + + + + + + + Statistical operations on data + + + + + + + + Extended tyoe for same as {{property(DataItem::units)}}. See + {{package(Device Information Model)}}. + + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + + Extended tyoe for The units supported for the source equipment that can + be converted into MTC Units. + + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + measure of viscosity. + + + + + + + rotational velocity in degrees per minute. + + + + + + + temperature in Fahrenheit. + + + + + + + feet. + + + + + + + feet per minute. + + + + + + + feet per second. + + + + + + + acceleration in feet per second squared. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in feet. + + + + + + + gallons per minute. + + + + + + + measurement of time in hours. + + + + + + + inches. + + + + + + + inches per minute. + + + + + + + inches per second. + + + + + + + acceleration in inches per second squared. + + + + + + + measure of torque in inch pounds. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in inches. + + + + + + + measurement of temperature. + + + + + + + measurement in kilowatt. + + + + + + + kilowatt hours which is 3.6 mega joules. + + + + + + + measurement of rate of flow of a fluid. + + + + + + + velocity in millimeters per minute. + + + + + + + measurement of time in minutes. + + + + + + + unsupported unit. + + + + + + + US pounds. + + + + + + + pressure in pounds per square inch (PSI). + + + + + + + angle in radians. + + + + + + + velocity in radians per minute. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + pressure in Bar. + + + + + + + pressure in Torr. + + + + + + + pressure in Millimeter of Mercury (mmHg). + + + + + + + pascal per minute. + + + + + + + $$MASS\times GRAVITATIONAL_ACCELERATION$$ (g) given in + `METER/SECOND^2`. + + + + + + + acceleration relative to earth's gravity given in + `METER/SECOND^2`. > Note 1 to entry: At different points on + Earth's surface, the free-fall acceleration ranges from 9.764 + to 9.834 m/s2 (Wikipedia: Gravitational Acceleration). The constant + can be customized depending on the location in the universe. > + Note 2 to entry: In the standard, it is assumed that Earth's + average value of gravitational acceleration is 9.90665 m/s2. + + + + + + + electric charge in ampere hour. + + + + + + + change of geometric volume in cubic foot per hour. + + + + + + + change of geometric volume in cubic foot per minute. + + + + + + + geometric area in inches. + + + + + + + geometric volume in feet. + + + + + + + inch per revolution. + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + + The coordinate system to be used for the position + + + + + + + unchangeable coordinate system that has machine zero as its origin. + + + + + + + coordinate system that represents the working area for a particular + workpiece whose origin is shifted within the `MACHINE` coordinate + system. If the `WORK` coordinates are not currently defined in the + piece of equipment, the `MACHINE` coordinates will be used. + + + + + + + + + Extended tyoe for The reset intervals + + + + + + + + + + The reset intervals + + + + + + + {{term(observation)}} of the {{block(DataItem)}} that is measuring + an action or operation is to be reset upon completion of that action + or operation. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 12-month period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 24-hour period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is not reset and + accumulates for the entire life of the piece of equipment. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset upon + completion of a maintenance event. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a monthly period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset when + power was applied to the piece of equipment after a planned or + unplanned interruption of power has occurred. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a work shift. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 7-day period. + + + + + + + + + The reset intervals + + + + + + + + + The document version + + + + + + + time the file was created. + + + + + + + Indicates that this was a test document + + + + + + + The unique instance identifier of this agent process + + + + + + + The sender of the message + + + + + + + A timestamp in 8601 format of the last update of the Device + information for any device + + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the data + management within the {{term(agent)}}. + + + + + + + + The document version + + + + + + + time the file was created. + + + + + + + Indicates that this was a test document + + + + + + + The unique instance identifier of this agent process + + + + + + + The sender of the message + + + + + + + The size of the agent's buffer. + + + + + + + + + + root entity of an {{term(MTConnectErrors Response Document)}} that + contains the {{term(Error Information Model)}}. + ![MTConnectError](figures/MTConnectErrors.png + "MTConnectError"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectError)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the + data management within the {{term(agent)}}. + + + + + + + + error encountered by an {{term(agent)}} when responding to a + {{term(request)}}. + + + + + + + {{block(Errors)}} groups one or more {{block(Error)}} entities. + See {{sect(Error)}}. > Note: When compatibility with Version + 1.0.1 and earlier of the MTConnect Standard is required for an + implementation, the {{term(MTConnectErrors Response Document)}} + contains only a single {{block(Error)}} entity and the + {{block(Errors)}} entity **MUST NOT** appear in the document. + + + + + + + + + + {{block(Errors)}} groups one or more {{block(Error)}} entities. See + {{sect(Error)}}. > Note: When compatibility with Version 1.0.1 and + earlier of the MTConnect Standard is required for an implementation, the + {{term(MTConnectErrors Response Document)}} contains only a single + {{block(Error)}} entity and the {{block(Errors)}} entity **MUST NOT** + appear in the document. + + + + + + + error encountered by an {{term(agent)}} when responding to a + {{term(request)}}. + + + + + + + + + The text description of the error + + + + + + + + The error code + + + + + + + The request did not have sufficient permissions to perform the + request. + + + + + + + The device specified in the URI could not be found. + + + + + + + The sequence number was beyond the end of the buffer. + + + + + + + The count given is too large. + + + + + + + The URI provided was incorrect. + + + + + + + The request was not one of the three specified requests. + + + + + + + Contact the software provider, the agent did not behave correctly. + + + + + + + The xpath could not be parsed. Invalid syntax. + + + + + + + The request is not supported by this implementation + + + + + + + The asset ID cannot be found + + + + + + + + + error encountered by an {{term(agent)}} when responding to a + {{term(request)}}. + + + + + + + + The error code + + + + + + + \ No newline at end of file diff --git a/schemas/MTConnectError_2.5_1.0.xsd b/schemas/MTConnectError_2.5_1.0.xsd new file mode 100644 index 000000000..0f659c0a7 --- /dev/null +++ b/schemas/MTConnectError_2.5_1.0.xsd @@ -0,0 +1,4667 @@ + + + + + + + root entity of an {{term(MTConnectErrors Response Document)}} that + contains the {{term(Error Information Model)}}. + ![MTConnectError](figures/MTConnectErrors.png + "MTConnectError"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectError)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + The sender of the message + + + + + + + + The date and time the document was created + + + + + + + + A sequence number + + + + + + + + + + + A debugging flag for testing. + + + + + + + + The instance number of the agent, used for fault tolerance + + + + + + + + + + + The size of the agents buffer + + + + + + + + + + + The time the sample was reported + + + + + + + + The time a sample occurred + + + + + + + + A version number + + + + + + + + A short name for any element + + + + + + + + A universally unique id that uniquely identifies the element for + it's entire life + + + + + + + + A serial number for a piece of equipment + + + + + + + + The measurement source + + + + + + + + A sample rate in milliseconds per sample + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + + An identifier + + + + + + + + The number significant digits + + + + + + + + The item's reference to the Device model composition + + + + + + + + A length of time in seconds + + + + + + + + A flag indicating the item has been removed + + + + + + + + The key for adata set + + + + + + + + A timestamp in 8601 format of the last update of the Device information + for any device + + + + + + + + The unique id of the asset + + + + + + + + An asset type + + + + + + + + The maximum number of assets + + + + + + + + + + + The number of assets + + + + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + The limit of a value + + + + + + + + Common floating point sample value + + + + + + + + + + + + A three dimensional value 'X Y Z' or 'A B C' + + + + + + + + + + + A description + + + + + + + + Extended tyoe for The types of measurements available + + + + + + + + + + The types of measurements available + + + + + + + positive rate of change of velocity. + + + + + + + accumulated time for an activity or event. + + + + + + + strength of electrical current. **DEPRECATED** in *Version 1.6*. + Replaced by `AMPERAGE_AC` and `AMPERAGE_DC`. + + + + + + + angular position. + + + + + + + positive rate of change of angular velocity. + + + + + + + rate of change of angular position. + + + + + + + feedrate of a linear axis. + + + + + + + fluid capacity of an object or container. + + + + + + + geometric capacity of an object or container. + + + + + + + percentage of one component within a mixture of components. + + + + + + + ability of a material to conduct electricity. + + + + + + + speed difference (relative velocity) between the cutting mechanism + and the surface of the workpiece it is operating on. + + + + + + + volumetric mass of a material per unit volume of that material. + + + + + + + rate of change in spatial volume of material deposited in an + additive manufacturing process. + + + + + + + density of the material deposited in an additive manufacturing + process per unit of volume. + + + + + + + mass of the material deposited in an additive manufacturing process. + + + + + + + rate at which a spatial volume of material is deposited in an + additive manufacturing process. + + + + + + + spatial volume of material to be deposited in an additive + manufacturing process. + + + + + + + change in position of an object. + + + + + + + {{block(Wattage)}} used or generated by a component over an interval + of time. + + + + + + + amount of time a piece of equipment or a sub-part of a piece of + equipment has performed specific activities. + + + + + + + amount of a substance remaining compared to the planned maximum + amount of that substance. + + + + + + + rate of flow of a fluid. + + + + + + + number of occurrences of a repeating event per unit time. + + + + + + + position in three-dimensional space. **DEPRECATED** in Version 1.1. + + + + + + + length of an object. + + + + + + + level of a resource. **DEPRECATED** in *Version 1.2*. See + `FILL_LEVEL`. + + + + + + + {{term(force)}} applied to a mass in one direction only. + + + + + + + actual versus the standard rating of a piece of equipment. + + + + + + + mass of an object(s) or an amount of material. + + + + + + + feedrate for the axes, or a single axis, associated with a + {{block(Path)}} component. + + + + + + + feedrate for the axes, or a single axis. + + + + + + + position of a control point associated with a {{block(Controller)}} + or a {{block(Path)}}. + + + + + + + acidity or alkalinity of a solution. + + + + + + + point along an axis in a {{term(cartesian coordinate system)}}. + + + + + + + ratio of real power flowing to a load to the apparent power in that + AC circuit. + + + + + + + force per unit area measured relative to atmospheric pressure. + Commonly referred to as gauge pressure. + + + + + + + amount of time a piece of equipment has performed different types of + activities associated with the process being performed at that piece + of equipment. + + + + + + + degree to which a substance opposes the passage of an electric + current. + + + + + + + rotational speed of a rotary axis. + + + + + + + sound level or sound pressure level relative to atmospheric + pressure. + + + + + + + rotational speed of the rotary axis. **DEPRECATED** in *Version + 1.2*. Replaced by `ROTARY_VELOCITY`. + + + + + + + amount of deformation per unit length of an object when a load is + applied. + + + + + + + degree of hotness or coldness measured on a definite scale. + + + + + + + force that stretches or elongates an object. + + + + + + + angular displacement. + + + + + + + turning force exerted on an object or by an object. + + + + + + + rate of change of position of a {{block(Component)}}. + + + + + + + fluid's resistance to flow. + + + + + + + electrical potential between two points. **DEPRECATED** in *Version + 1.6*. Replaced by `VOLTAGE_AC` and `VOLTAGE_DC`. + + + + + + + apparent power in an electrical circuit, equal to the product of + root-mean-square (RMS) voltage and RMS current (commonly referred to + as VA). + + + + + + + reactive power in an AC electrical circuit (commonly referred to as + VAR). + + + + + + + fluid volume of an object or container. + + + + + + + geometric volume of an object or container. + + + + + + + power flowing through or dissipated by an electrical circuit or + piece of equipment. + + + + + + + electrical current that reverses direction at regular short + intervals. + + + + + + + electric current flowing in one direction only. + + + + + + + electrical potential between two points in an electrical circuit in + which the current periodically reverses direction. + + + + + + + electrical potential between two points in an electrical circuit in + which the current is unidirectional. + + + + + + + dimension of an entity relative to the X direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Y direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Z direction of the referenced + coordinate system. + + + + + + + dimension of a diameter. + + + + + + + angular position of a plane or vector relative to a {{term(cartesian + coordinate system)}} + + + + + + + amount of water vapor present expressed as a percent to reach + saturation at the same temperature. + + + + + + + amount of water vapor expressed in grams per cubic meter. + + + + + + + ratio of the water vapor present over the total weight of the water + vapor and air present expressed as a percent. + + + + + + + average rate of change of values for data items in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + average rate of change of values for assets in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + change of pressure per unit time. + + + + + + + negative rate of change of velocity. + + + + + + + negative rate of change of angular velocity. + + + + + + + force per unit area measured relative to a vacuum. + + + + + + + percentage open where 100% is fully open and 0% is fully closed. + + + + + + + temperature at which moisture begins to condense, corresponding to + saturation for a given absolute humidity. + + + + + + + force relative to earth's gravity. + + + + + + + acceleration relative to Earth's gravity of 9.80665 + `METER/SECOND^2`. + + + + + + + maximum rated charge a battery is capable of maintaining based on + the battery discharging at a specified current over a specified time + period. + + + + + + + value of current being drawn from the {{block(Component)}}. + + + + + + + value of the current being supplied to the {{block(Component)}} for + the purpose of charging. + + + + + + + value of the battery's present capacity expressed as a + percentage of the battery's maximum rated capacity. + + + + + + + difference between actual and commanded position at the end of a + motion. + + + + + + + difference between actual and commanded position at any specific + point in time during a motion. + + + + + + + difference between the commanded encoder/resolver position, and the + actual encoder/resolver position when motion is complete. + + + + + + + angular difference between the commanded encoder/resolver position, + and the actual encoder/resolver position when motion is complete. + + + + + + + difference between the commanded encoder/resolver position and the + actual encoder/resolver position at any specified point in time + during a motion. + + + + + + + angular difference between the commanded encoder/resolver position + and the actual encoder/resolver position at any specified point in + time during a motion. + + + + + + + absolute value of the change in position along a vector. + + + + + + + absolute value of the change in angular position around a vector + + + + + + + point in a {{term(cartesian coordinate system)}}. + + + + + + + set of axes currently associated with a {{block(Path)}} or + {{block(Controller)}}. + + + + + + + operational state of an apparatus for moving or controlling a + mechanism or system. + + + + + + + **DEPRECATED:** Replaced with `CONDITION` category data items in + Version 1.1.0. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been added or + changed. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been removed. + + + + + + + {{term(agent)}}'s ability to communicate with the data source. + + + + + + + describes the way the axes will be associated to each other. This is + used in conjunction with `COUPLED_AXES` to indicate the way they are + interacting. + + + + + + + value of a signal or calculation issued to adjust the feedrate of an + individual linear type axis. + + + + + + + state of the axis lockout function when power has been removed and + the axis is allowed to move freely. + + + + + + + state of a {{block(Linear)}} or {{block(Rotary)}} component + representing an axis. + + + + + + + line of code or command being executed by a {{block(Controller)}} + entity. + + + + + + + total count of the number of blocks of program code that have been + executed since execution started. + + + + + + + state of an interlock function or control logic state intended to + prevent the associated {{block(Chuck)}} component from being + operated. + + + + + + + operating state of a mechanism that holds a part or stock material + during a manufacturing process. It may also represent a mechanism + that holds any other mechanism in place within a piece of equipment. + + + + + + + programmatic code being executed. **DEPRECATED** in *Version 1.1*. + + + + + + + operating state of a mechanism represented by a + {{block(Composition)}} entity. + + + + + + + current mode of the {{block(Controller)}} component. + + + + + + + setting or operator selection that changes the behavior of a piece + of equipment. + + + + + + + set of associated axes. + + + + + + + time and date code associated with a material or other physical + item. + + + + + + + identifier of another piece of equipment that is temporarily + associated with a component of this piece of equipment to perform a + particular function. + + + + + + + direction of motion. + + + + + + + operational state of a {{block(Door)}} component or composition + element. + + + + + + + state of the emergency stop signal for a piece of equipment, + controller path, or any other component or subsystem of a piece of + equipment. + + + + + + + indication of whether the end of a piece of bar stock being feed by + a bar feeder has been reached. + + + + + + + indication that a piece of equipment, or a sub-part of a piece of + equipment, is performing specific types of activities. + + + + + + + operating state of a {{block(Component)}}. + + + + + + + current intended production status of the {{block(Component)}}. + + + + + + + hardness of a material. + + + + + + + current line of code being executed. **DEPRECATED** in *Version + 1.4.0*. + + + + + + + identifier for a {{block(Block)}} of code in a {{block(Program)}}. + + + + + + + position of a block of program code within a control program. + + + + + + + identifier of a material used or consumed in the manufacturing + process. + + + + + + + identifies the layers of material applied to a part or product as + part of an additive manufacturing process. + + + + + + + information to be transferred from a piece of equipment to a client + software application. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + identifier for a pallet. + + + + + + + aggregate count of parts. + + + + + + + indication designating whether a part or work piece has been + detected or is present. + + + + + + + identifier of a part in a manufacturing operation. + + + + + + + identifier of a part or product moving through the manufacturing + process. **DEPRECATED** in *Version 1.7*. `PART_NUMBER` is now a + `subType` of `PART_KIND_ID`. + + + + + + + value of a signal or calculation issued to adjust the feedrate for + the axes associated with a {{block(Path)}} component that may + represent a single axis or the coordinated movement of multiple + axes. + + + + + + + describes the operational relationship between a {{block(Path)}} + entity and another {{block(Path)}} entity for pieces of equipment + comprised of multiple logical groupings of controlled axes or other + logical operations. + + + + + + + indication of the status of the source of energy for an entity to + allow it to perform its intended function or the state of an + enabling signal providing permission for the entity to perform its + functions. + + + + + + + status of the {{block(Component)}}. **DEPRECATED** in *Version + 1.1.0*. + + + + + + + time and date associated with an activity or event. + + + + + + + name of the logic or motion program being executed by the + {{block(Controller)}} component. + + + + + + + comment or non-executable statement in the control program. + + + + + + + indication of the status of the {{block(Controller)}} components + program editing mode. A program may be edited while another is + executed. + + + + + + + name of the program being edited. This is used in conjunction with + {{block(ProgramEdit)}} when in `ACTIVE` state. + + + + + + + non-executable header section of the control program. + + + + + + + {{term(URI)}} for the source file associated with + {{block(Program)}}. + + + + + + + defines whether the logic or motion program defined by + {{block(Program)}} is being executed from the local memory of the + controller or from an outside source. + + + + + + + indication of the nesting level within a control program that is + associated with the code or instructions that is currently being + executed. + + + + + + + current operating mode for a {{block(Rotary)}} type axis. + + + + + + + percentage change to the velocity of the programmed velocity for a + {{block(Rotary)}} axis. + + + + + + + serial number associated with a {{block(Component)}}, + {{block(Asset)}}, or {{block(Device)}}. + + + + + + + indication of the status of the spindle for a piece of equipment + when power has been removed and it is free to rotate. + + + + + + + identifier of an individual tool asset. + + + + + + + identifier for the tool group associated with a specific tool. + Commonly used to designate spare tools. + + + + + + + identifier of the tool currently in use for a given `Path`. + **DEPRECATED** in *Version 1.2.0*. See `TOOL_ASSET_ID`. + + + + + + + identifier assigned by the {{block(Controller)}} component to a + cutting tool when in use by a piece of equipment. + + + + + + + reference to the tool offset variables applied to the active cutting + tool. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + data whose meaning may change over time due to changes in the + operation of a piece of equipment or the process being executed on + that piece of equipment. + + + + + + + indication of the reason that {{block(Execution)}} is reporting a + value of `WAIT`. + + + + + + + identifier for the type of wire used as the cutting mechanism in + Electrical Discharge Machining or similar processes. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. **DEPRECATION WARNING**: Recommend using + `FIXTURE_ID` instead. + + + + + + + reference to offset variables for a work piece or part. + + + + + + + Operating System (OS) of a {{block(Component)}}. + + + + + + + embedded software of a {{block(Component)}} . + + + + + + + application on a {{block(Component)}}. + + + + + + + software library on a {{block(Component)}} + + + + + + + hardware of a {{block(Component)}}. + + + + + + + network details of a {{block(Component)}}. + + + + + + + three space angular displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + three space linear displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + {{term(UUID)}} of new device added to an {{term(MTConnect Agent)}}. + + + + + + + {{term(UUID)}} of a device removed from an {{term(MTConnect + Agent)}}. + + + + + + + {{term(UUID)}} of the device whose {{term(metadata)}} has changed. + + + + + + + status of the connection between an {{term(adapter)}} and an + {{term(agent)}}. + + + + + + + originator’s software version of the {{term(adapter)}}. + + + + + + + {{term(URI)}} of the {{term(adapter)}}. + + + + + + + reference version of the MTConnect Standard supported by the + {{term(adapter)}}. + + + + + + + {{term(attachment)}} between a sensor and an entity. + + + + + + + state or condition of a part. + + + + + + + identifier of a process being executed by the device. + + + + + + + identifier given to link the individual occurrence to a group of + related occurrences, such as a process step in a process plan. + + + + + + + identifier given to link the individual occurrence to a class of + processes or process definition. + + + + + + + identifier given to a collection of individual parts. + + + + + + + identifier given to link the individual occurrence to a class of + parts, typically distinguished by a particular part design. + + + + + + + identifier given to a distinguishable, individual part. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. **DEPRECATION WARNING**. Recommend using + `CONTROL_LIMITS`. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. **DEPRECATION WARNING**. Recommend using + `SPECIFICATION_LIMITS`. + + + + + + + set of limits used to trigger warning or alarm indicators. + **DEPRECATION WARNING**. Recommend using `ALARM_LIMITS`. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, load materials, parts, or other items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, unload materials, parts, or other + items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, transfer materials, parts, or other + items from one location to another. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, activate or be performed. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, deactivate or cease. + + + + + + + accumulation of the number of times a cyclic function has attempted + to, or is planned to attempt to execute. + + + + + + + state of a valve is one of open, closed, or transitioning between + the states. + + + + + + + state or operating mode of a {{block(Lock)}}. + + + + + + + particular condition of the process occurrence at a specific time. + + + + + + + particular condition of the part occurrence at a specific time. + + + + + + + state of {{block(Component)}} or {{block(Composition)}} that + describes the automatic or manual operation of the entity. + + + + + + + {{term(data set)}} of the number of {{termplural(Asset)}} of a given + type for a {{term(Device)}}. + + + + + + + actions or activities to be performed in support of a piece of + equipment. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. + + + + + + + interpretation of `PART_COUNT`. + + + + + + + time provided by a timing device at a specific point in time. + + + + + + + name of the host computer supplying data. + + + + + + + number of the TCP/IP or UDP/IP port for the connection endpoint. + + + + + + + indication designating whether a leak has been detected. + + + + + + + present status of the battery. + + + + + + + {{term(UUID)}} of a {{term(feature)}}. {{cite(ISO 10303 AP + 242/239)}}. + + + + + + + detection result of a sensor. + + + + + + + {{block(Event)}} that represents a {{block(Component)}} where the + {{block(EntryDefinition)}} identifies the {{block(Component)}} and + the {{block(CellDefinition)}}s define the + {{block(Component)}}'s observed {{block(DataItem)}}s. + + + + + + + properties of each addressable work offset. + + + + + + + properties of each addressable tool offset. + + + + + + + assessing elements of a {{term(feature)}}. + + + + + + + {{term(UUID)}} of the {{term(characteristic)}}. + + + + + + + class of measurement being performed. {{cite(QIF 3:2018 Section + 6.3)}} + + + + + + + measurement based on the measurement type. + + + + + + + engineering units of the measurement. + + + + + + + pass/fail result of the measurement. + + + + + + + method used to compute {{term(standard uncertainty)}}. + + + + + + + {{term(uncertainty)}} specified by {{block(UncertaintyType)}}. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. + + + + + + + set of limits used to trigger warning or alarm indicators. + + + + + + + references the {{block(CuttingToolLifeCycle)}} + {{block(CuttingItem)}} index related to the + {{property(CuttingItem::indices)}} of the currently active cutting + tool edge. + + + + + + + structured information that allows the unambiguous determination of + an object for purposes of identification and location. {{cite(ISO + 19160-4:2017)}} + + + + + + + active energy source for the {{block(Component)}}. + + + + + + + textual description of the location of an object or activity. + + + + + + + dimension between two surfaces of an object, usually the dimension + of smallest measure, for example an additive layer, or a depth of + cut. + + + + + + + absolute geographic location defined by two coordinates, longitude + and latitude and an elevation. + + + + + + + indication that the piece of equipment has experienced a + communications failure. + + + + + + + indication that the value of the data associated with a measured + value or a calculation is outside of an expected range. + + + + + + + indication that an error occurred in the logic program or + programmable logic controller (PLC) associated with a piece of + equipment. + + + + + + + indication that an error occurred in the motion program associated + with a piece of equipment. + + + + + + + general purpose indication associated with an electronic component + of a piece of equipment or a controller that represents a fault that + is not associated with the operator, program, or hardware. + + + + + + + indication of a fault associated with an actuator. + + + + + + + operational state of an {{block(Interface)}}. + + + + + + + operating state of the service to advance material or feed product + to a piece of equipment from a continuous or bulk source. + + + + + + + operating state of the service to change the type of material or + product being loaded or fed to a piece of equipment. + + + + + + + operating state of the service to remove or retract material or + product. + + + + + + + operating state of the service to change the part or product + associated with a piece of equipment to a different part or product. + + + + + + + operating state of the service to load a piece of material or + product. + + + + + + + operating state of the service to unload a piece of material or + product. + + + + + + + operating state of the service to open a chuck. + + + + + + + operating state of the service to open a door. + + + + + + + operating state of the service to close a chuck. + + + + + + + operating state of the service to close a door. + + + + + + + A user variable + + + + + + + + + The types of measurements available + + + + + + + + Extended tyoe for The sub-types for a measurement + + + + + + + + + + The sub-types for a measurement + + + + + + + relating to or derived in the simplest manner from the fundamental + units or measurements. + + + + + + + indication of the operating state of a mechanism. + + + + + + + measured or reported value of an {{term(observation)}}. + + + + + + + all actions, items, or activities being counted independent of the + outcome. + + + + + + + measurement of alternating voltage or current. If not specified + further in statistic, defaults to RMS voltage. **DEPRECATED** in + *Version 1.6*. + + + + + + + A-Scale weighting factor on the frequency scale. + + + + + + + when multiple locations on a piece of bar stock being feed by a bar + feeder are referenced as the indication of whether the end of that + piece of bar stock has been reached. + + + + + + + actions, items, or activities being counted that do not conform to + specification or expectation. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + B-Scale weighting factor on the frequency scale. + + + + + + + directive value including adjustments such as an offset or + overrides. + + + + + + + amount of material consumed from an object or container during a + manufacturing process. + + + + + + + state of the enabling signal or control logic that enables or + disables the function or operation of the entity. + + + + + + + C-Scale weighting factor on the frequency scale. + + + + + + + elapsed time of a temporary halt of action. + + + + + + + DC current or voltage. **DEPRECATED** in *Version 1.6*. + + + + + + + setting or operator selection used to execute a test mode to confirm + the execution of machine functions. + + + + + + + D-Scale weighting factor on the frequency scale. + + + + + + + relating to the expiration or end of useful life for a material or + other physical item. + + + + + + + relating to the first use of a material or other physical item. + + + + + + + actions, items, or activities being counted that conform to + specification or expectation. + + + + + + + relating to or derived from the last {{term(observation)}}. + + + + + + + relating to momentary activation of a function or a movement. + **DEPRECATION WARNING**: May be deprecated in the future. + + + + + + + indication of the position of a mechanism that may move in a lateral + direction. + + + + + + + scale to measure the elasticity of a surface. + + + + + + + reference to a length type tool offset variable. + + + + + + + state of the power source. + + + + + + + direction of motion of a linear motion. + + + + + + + indication that the subparts of a piece of equipment are under load. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + relating to the primary logic or motion program currently being + executed. + + + + + + + relating to maintenance on the piece of equipment. + + + + + + + indication of the state of an operator controlled interlock that can + inhibit the ability to initiate an unclamp action of an + electronically controlled chuck. + + + + + + + related to the production of a material or other physical item. + + + + + + + maximum value. + + + + + + + minimum value. + + + + + + + scale to measure the resistance to scratching of a surface. + + + + + + + indication of the open or closed state of a mechanism. + + + + + + + no weighting factor on the frequency scale. + + + + + + + piece of equipment that is powered or performing any activity. + + + + + + + relating to the person currently responsible for operating the piece + of equipment. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + overridden value. + + + + + + + piece of equipment is powered and functioning or + {{block(Component)}} that are required to remain on are powered. + + + + + + + main or principle. + + + + + + + position provided by a measurement probe. **DEPRECATION WARNING**: + May be deprecated in the future. + + + + + + + relating to production of a part or product on a piece of equipment. + + + + + + + directive value without offsets and adjustments. + + + + + + + reference to a radial type tool offset variable. + + + + + + + performing an operation faster or in less time than nominal rate. + + + + + + + remaining measure or count of an action, object or activity. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + direction of a rotary motion using the right hand rule convention. + + + + + + + identity of a control program that is used to specify the order of + execution of other programs. + + + + + + + relating to the preparation of a piece of equipment for production + or restoring the piece of equipment to a neutral state after + production. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + standard measure of an object or an action. + + + + + + + boundary when an activity or an event commences. + + + + + + + indication of the activation state of a mechanism represented by a + {{block(Composition)}}. + + + + + + + goal of the operation or process. + + + + + + + relating to the end or completion of an activity or event. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + remaining usable measure of an object or action. + + + + + + + indication of the position of a mechanism that may move in a + vertical direction. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + piece of equipment performing any activity, the equipment is active + and performing a function under load or not. + + + + + + + IPV4 network address of the {{block(Component)}}. + + + + + + + IPV6 network address of the {{block(Component)}}. + + + + + + + Gateway for the {{block(Component)}} network. + + + + + + + SubNet mask for the {{block(Component)}} network. + + + + + + + layer2 Virtual Local Network (VLAN) ID for the {{block(Component)}} + network. + + + + + + + Media Access Control Address. The unique physical address of the + network hardware. + + + + + + + identifies whether the connection type is wireless. + + + + + + + license code to validate or activate the hardware or software. + + + + + + + version of the hardware or software. + + + + + + + date the hardware or software was released for general use. + + + + + + + date the hardware or software was installed. + + + + + + + corporate identity for the maker of the hardware or software. + + + + + + + universally unique identifier as specified in ISO 11578 or RFC 4122. + + + + + + + serial number that uniquely identifies a specific part. + + + + + + + material that is used to produce parts. + + + + + + + group of parts tracked as a lot. + + + + + + + group of parts produced in a batch. + + + + + + + material heat number. + + + + + + + particular part design or model. + + + + + + + group of parts having similarities in geometry, manufacturing + process, and/or functions. + + + + + + + word or set of words by which a part is known, addressed, or + referred to. + + + + + + + step in the process plan that this occurrence corresponds to. + + + + + + + process plan that a process occurrence belongs to. + + + + + + + authorization of a process occurrence. + + + + + + + word or set of words by which a process being executed (process + occurrence) by the device is known, addressed, or referred to. + + + + + + + reference to a ISO 10303 Executable. + + + + + + + associated with the completion of an activity or event. + + + + + + + relating to logic or motion program currently executing. + + + + + + + actions or activities that were attempted , but failed to complete + or resulted in an unexpected or unacceptable outcome. + + + + + + + actions or activities that were attempted, but terminated before + they could be completed. + + + + + + + boundary when an activity or an event terminates. + + + + + + + amount discarded. + + + + + + + amount included in the {{term(part)}}. + + + + + + + {{term(request)}} by an {{block(Interface)}} for a task. + + + + + + + {{term(response)}} by an {{block(Interface)}} to a {{term(request)}} + for a task. + + + + + + + phase or segment of a recipe or program. + + + + + + + phase of a recipe process. + + + + + + + process as part of product production; can be a subprocess of a + larger process. + + + + + + + step of a discrete manufacturing process. + + + + + + + observed as a binary data type. + + + + + + + observed as a boolean data type. + + + + + + + observed as a set containing a restricted number of discrete values + where each discrete value is named and unique. {{cite(ISO + 21961:2003, 013)}} + + + + + + + indicated by the presence or existence of something. + + + + + + + model info of the hardware or software. + + + + + + + + + The sub-types for a measurement + + + + + + + + Extended tyoe for Statistical operations on data + + + + + + + + + + Statistical operations on data + + + + + + + mathematical average value calculated for the data item during the + calculation period. + + + + + + + **DEPRECATED** in *Version 1.6*. ~~A measure of the + "peakedness" of a probability distribution; i.e., the + shape of the distribution curve.~~ + + + + + + + maximum or peak value recorded for the data item during the + calculation period. + + + + + + + middle number of a series of numbers. + + + + + + + minimum value recorded for the data item during the calculation + period. + + + + + + + number in a series of numbers that occurs most often. + + + + + + + difference between the maximum and minimum value of a data item + during the calculation period. Also represents Peak-to-Peak + measurement in a waveform. + + + + + + + mathematical Root Mean Square (RMS) value calculated for the data + item during the calculation period. + + + + + + + statistical Standard Deviation value calculated for the data item + during the calculation period. + + + + + + + + + Statistical operations on data + + + + + + + + Extended tyoe for same as {{property(DataItem::units)}}. See + {{package(Device Information Model)}}. + + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + + Extended tyoe for The units supported for the source equipment that can + be converted into MTC Units. + + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + measure of viscosity. + + + + + + + rotational velocity in degrees per minute. + + + + + + + temperature in Fahrenheit. + + + + + + + feet. + + + + + + + feet per minute. + + + + + + + feet per second. + + + + + + + acceleration in feet per second squared. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in feet. + + + + + + + gallons per minute. + + + + + + + measurement of time in hours. + + + + + + + inches. + + + + + + + inches per minute. + + + + + + + inches per second. + + + + + + + acceleration in inches per second squared. + + + + + + + measure of torque in inch pounds. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in inches. + + + + + + + measurement of temperature. + + + + + + + measurement in kilowatt. + + + + + + + kilowatt hours which is 3.6 mega joules. + + + + + + + measurement of rate of flow of a fluid. + + + + + + + velocity in millimeters per minute. + + + + + + + measurement of time in minutes. + + + + + + + unsupported unit. + + + + + + + US pounds. + + + + + + + pressure in pounds per square inch (PSI). + + + + + + + angle in radians. + + + + + + + velocity in radians per minute. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + pressure in Bar. + + + + + + + pressure in Torr. + + + + + + + pressure in Millimeter of Mercury (mmHg). + + + + + + + pascal per minute. + + + + + + + $$MASS\times GRAVITATIONAL_ACCELERATION$$ (g) given in + `METER/SECOND^2`. + + + + + + + acceleration relative to earth's gravity given in + `METER/SECOND^2`. > Note 1 to entry: At different points on + Earth's surface, the free-fall acceleration ranges from 9.764 + to 9.834 m/s2 (Wikipedia: Gravitational Acceleration). The constant + can be customized depending on the location in the universe. > + Note 2 to entry: In the standard, it is assumed that Earth's + average value of gravitational acceleration is 9.90665 m/s2. + + + + + + + electric charge in ampere hour. + + + + + + + change of geometric volume in cubic foot per hour. + + + + + + + change of geometric volume in cubic foot per minute. + + + + + + + geometric area in inches. + + + + + + + geometric volume in feet. + + + + + + + inch per revolution. + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + + The coordinate system to be used for the position + + + + + + + unchangeable coordinate system that has machine zero as its origin. + + + + + + + coordinate system that represents the working area for a particular + workpiece whose origin is shifted within the `MACHINE` coordinate + system. If the `WORK` coordinates are not currently defined in the + piece of equipment, the `MACHINE` coordinates will be used. + + + + + + + + + Extended tyoe for The reset intervals + + + + + + + + + + The reset intervals + + + + + + + {{term(observation)}} of the {{block(DataItem)}} that is measuring + an action or operation is to be reset upon completion of that action + or operation. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 12-month period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 24-hour period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is not reset and + accumulates for the entire life of the piece of equipment. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset upon + completion of a maintenance event. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a monthly period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset when + power was applied to the piece of equipment after a planned or + unplanned interruption of power has occurred. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a work shift. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 7-day period. + + + + + + + + + The reset intervals + + + + + + + + + The document version + + + + + + + time the file was created. + + + + + + + Indicates that this was a test document + + + + + + + The unique instance identifier of this agent process + + + + + + + The sender of the message + + + + + + + A timestamp in 8601 format of the last update of the Device + information for any device + + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the data + management within the {{term(agent)}}. + + + + + + + + The document version + + + + + + + time the file was created. + + + + + + + Indicates that this was a test document + + + + + + + The unique instance identifier of this agent process + + + + + + + The sender of the message + + + + + + + The size of the agent's buffer. + + + + + + + + + + root entity of an {{term(MTConnectErrors Response Document)}} that + contains the {{term(Error Information Model)}}. + ![MTConnectError](figures/MTConnectErrors.png + "MTConnectError"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectError)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the + data management within the {{term(agent)}}. + + + + + + + + error encountered by an {{term(agent)}} when responding to a + {{term(request)}}. + + + + + + + {{block(Errors)}} groups one or more {{block(Error)}} entities. + See {{sect(Error)}}. > Note: When compatibility with Version + 1.0.1 and earlier of the MTConnect Standard is required for an + implementation, the {{term(MTConnectErrors Response Document)}} + contains only a single {{block(Error)}} entity and the + {{block(Errors)}} entity **MUST NOT** appear in the document. + + + + + + + + + + {{block(Errors)}} groups one or more {{block(Error)}} entities. See + {{sect(Error)}}. > Note: When compatibility with Version 1.0.1 and + earlier of the MTConnect Standard is required for an implementation, the + {{term(MTConnectErrors Response Document)}} contains only a single + {{block(Error)}} entity and the {{block(Errors)}} entity **MUST NOT** + appear in the document. + + + + + + + error encountered by an {{term(agent)}} when responding to a + {{term(request)}}. + + + + + + + + + The text description of the error + + + + + + + + The error code + + + + + + + The request did not have sufficient permissions to perform the + request. + + + + + + + The device specified in the URI could not be found. + + + + + + + The sequence number was beyond the end of the buffer. + + + + + + + The count given is too large. + + + + + + + The URI provided was incorrect. + + + + + + + The request was not one of the three specified requests. + + + + + + + Contact the software provider, the agent did not behave correctly. + + + + + + + The xpath could not be parsed. Invalid syntax. + + + + + + + The request is not supported by this implementation + + + + + + + The asset ID cannot be found + + + + + + + + + error encountered by an {{term(agent)}} when responding to a + {{term(request)}}. + + + + + + + + The error code + + + + + + + \ No newline at end of file diff --git a/schemas/MTConnectStreams_2.5.xsd b/schemas/MTConnectStreams_2.5.xsd new file mode 100644 index 000000000..8fc89d234 --- /dev/null +++ b/schemas/MTConnectStreams_2.5.xsd @@ -0,0 +1,46228 @@ + + + + + + + root entity of an {{term(MTConnectStreams Response Document)}} that + contains the {{term(Observation Information Model)}} of one or more + {{block(Device)}} entities. + ![MTConnectStreams](figures/MTConnectStreams.png + "MTConnectStreams"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectStreams)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + The sender of the message + + + + + + + + The date and time the document was created + + + + + + + + A sequence number + + + + + + + + + + + A debugging flag for testing. + + + + + + + + The instance number of the agent, used for fault tolerance + + + + + + + + + + + The size of the agents buffer + + + + + + + + + + + The time the sample was reported + + + + + + + + The time a sample occurred + + + + + + + + A version number + + + + + + + + A short name for any element + + + + + + + + A universally unique id that uniquely identifies the element for + it's entire life + + + + + + + + A serial number for a piece of equipment + + + + + + + + The measurement source + + + + + + + + A sample rate in milliseconds per sample + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + + An identifier + + + + + + + + The number significant digits + + + + + + + + The item's reference to the Device model composition + + + + + + + + A length of time in seconds + + + + + + + + A flag indicating the item has been removed + + + + + + + + The key for adata set + + + + + + + + A timestamp in 8601 format of the last update of the Device information + for any device + + + + + + + + The unique id of the asset + + + + + + + + An asset type + + + + + + + + The maximum number of assets + + + + + + + + + + + The number of assets + + + + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + The limit of a value + + + + + + + + Common floating point sample value + + + + + + + + + + + + A three dimensional value 'X Y Z' or 'A B C' + + + + + + + + + + + A description + + + + + + + + Extended tyoe for The types of measurements available + + + + + + + + + + The types of measurements available + + + + + + + positive rate of change of velocity. + + + + + + + accumulated time for an activity or event. + + + + + + + strength of electrical current. **DEPRECATED** in *Version 1.6*. + Replaced by `AMPERAGE_AC` and `AMPERAGE_DC`. + + + + + + + angular position. + + + + + + + positive rate of change of angular velocity. + + + + + + + rate of change of angular position. + + + + + + + feedrate of a linear axis. + + + + + + + fluid capacity of an object or container. + + + + + + + geometric capacity of an object or container. + + + + + + + percentage of one component within a mixture of components. + + + + + + + ability of a material to conduct electricity. + + + + + + + speed difference (relative velocity) between the cutting mechanism + and the surface of the workpiece it is operating on. + + + + + + + volumetric mass of a material per unit volume of that material. + + + + + + + rate of change in spatial volume of material deposited in an + additive manufacturing process. + + + + + + + density of the material deposited in an additive manufacturing + process per unit of volume. + + + + + + + mass of the material deposited in an additive manufacturing process. + + + + + + + rate at which a spatial volume of material is deposited in an + additive manufacturing process. + + + + + + + spatial volume of material to be deposited in an additive + manufacturing process. + + + + + + + change in position of an object. + + + + + + + {{block(Wattage)}} used or generated by a component over an interval + of time. + + + + + + + amount of time a piece of equipment or a sub-part of a piece of + equipment has performed specific activities. + + + + + + + amount of a substance remaining compared to the planned maximum + amount of that substance. + + + + + + + rate of flow of a fluid. + + + + + + + number of occurrences of a repeating event per unit time. + + + + + + + position in three-dimensional space. **DEPRECATED** in Version 1.1. + + + + + + + length of an object. + + + + + + + level of a resource. **DEPRECATED** in *Version 1.2*. See + `FILL_LEVEL`. + + + + + + + {{term(force)}} applied to a mass in one direction only. + + + + + + + actual versus the standard rating of a piece of equipment. + + + + + + + mass of an object(s) or an amount of material. + + + + + + + feedrate for the axes, or a single axis, associated with a + {{block(Path)}} component. + + + + + + + feedrate for the axes, or a single axis. + + + + + + + position of a control point associated with a {{block(Controller)}} + or a {{block(Path)}}. + + + + + + + acidity or alkalinity of a solution. + + + + + + + point along an axis in a {{term(cartesian coordinate system)}}. + + + + + + + ratio of real power flowing to a load to the apparent power in that + AC circuit. + + + + + + + force per unit area measured relative to atmospheric pressure. + Commonly referred to as gauge pressure. + + + + + + + amount of time a piece of equipment has performed different types of + activities associated with the process being performed at that piece + of equipment. + + + + + + + degree to which a substance opposes the passage of an electric + current. + + + + + + + rotational speed of a rotary axis. + + + + + + + sound level or sound pressure level relative to atmospheric + pressure. + + + + + + + rotational speed of the rotary axis. **DEPRECATED** in *Version + 1.2*. Replaced by `ROTARY_VELOCITY`. + + + + + + + amount of deformation per unit length of an object when a load is + applied. + + + + + + + degree of hotness or coldness measured on a definite scale. + + + + + + + force that stretches or elongates an object. + + + + + + + angular displacement. + + + + + + + turning force exerted on an object or by an object. + + + + + + + rate of change of position of a {{block(Component)}}. + + + + + + + fluid's resistance to flow. + + + + + + + electrical potential between two points. **DEPRECATED** in *Version + 1.6*. Replaced by `VOLTAGE_AC` and `VOLTAGE_DC`. + + + + + + + apparent power in an electrical circuit, equal to the product of + root-mean-square (RMS) voltage and RMS current (commonly referred to + as VA). + + + + + + + reactive power in an AC electrical circuit (commonly referred to as + VAR). + + + + + + + fluid volume of an object or container. + + + + + + + geometric volume of an object or container. + + + + + + + power flowing through or dissipated by an electrical circuit or + piece of equipment. + + + + + + + electrical current that reverses direction at regular short + intervals. + + + + + + + electric current flowing in one direction only. + + + + + + + electrical potential between two points in an electrical circuit in + which the current periodically reverses direction. + + + + + + + electrical potential between two points in an electrical circuit in + which the current is unidirectional. + + + + + + + dimension of an entity relative to the X direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Y direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Z direction of the referenced + coordinate system. + + + + + + + dimension of a diameter. + + + + + + + angular position of a plane or vector relative to a {{term(cartesian + coordinate system)}} + + + + + + + amount of water vapor present expressed as a percent to reach + saturation at the same temperature. + + + + + + + amount of water vapor expressed in grams per cubic meter. + + + + + + + ratio of the water vapor present over the total weight of the water + vapor and air present expressed as a percent. + + + + + + + average rate of change of values for data items in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + average rate of change of values for assets in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + change of pressure per unit time. + + + + + + + negative rate of change of velocity. + + + + + + + negative rate of change of angular velocity. + + + + + + + force per unit area measured relative to a vacuum. + + + + + + + percentage open where 100% is fully open and 0% is fully closed. + + + + + + + temperature at which moisture begins to condense, corresponding to + saturation for a given absolute humidity. + + + + + + + force relative to earth's gravity. + + + + + + + acceleration relative to Earth's gravity of 9.80665 + `METER/SECOND^2`. + + + + + + + maximum rated charge a battery is capable of maintaining based on + the battery discharging at a specified current over a specified time + period. + + + + + + + value of current being drawn from the {{block(Component)}}. + + + + + + + value of the current being supplied to the {{block(Component)}} for + the purpose of charging. + + + + + + + value of the battery's present capacity expressed as a + percentage of the battery's maximum rated capacity. + + + + + + + difference between actual and commanded position at the end of a + motion. + + + + + + + difference between actual and commanded position at any specific + point in time during a motion. + + + + + + + difference between the commanded encoder/resolver position, and the + actual encoder/resolver position when motion is complete. + + + + + + + angular difference between the commanded encoder/resolver position, + and the actual encoder/resolver position when motion is complete. + + + + + + + difference between the commanded encoder/resolver position and the + actual encoder/resolver position at any specified point in time + during a motion. + + + + + + + angular difference between the commanded encoder/resolver position + and the actual encoder/resolver position at any specified point in + time during a motion. + + + + + + + absolute value of the change in position along a vector. + + + + + + + absolute value of the change in angular position around a vector + + + + + + + point in a {{term(cartesian coordinate system)}}. + + + + + + + set of axes currently associated with a {{block(Path)}} or + {{block(Controller)}}. + + + + + + + operational state of an apparatus for moving or controlling a + mechanism or system. + + + + + + + **DEPRECATED:** Replaced with `CONDITION` category data items in + Version 1.1.0. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been added or + changed. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been removed. + + + + + + + {{term(agent)}}'s ability to communicate with the data source. + + + + + + + describes the way the axes will be associated to each other. This is + used in conjunction with `COUPLED_AXES` to indicate the way they are + interacting. + + + + + + + value of a signal or calculation issued to adjust the feedrate of an + individual linear type axis. + + + + + + + state of the axis lockout function when power has been removed and + the axis is allowed to move freely. + + + + + + + state of a {{block(Linear)}} or {{block(Rotary)}} component + representing an axis. + + + + + + + line of code or command being executed by a {{block(Controller)}} + entity. + + + + + + + total count of the number of blocks of program code that have been + executed since execution started. + + + + + + + state of an interlock function or control logic state intended to + prevent the associated {{block(Chuck)}} component from being + operated. + + + + + + + operating state of a mechanism that holds a part or stock material + during a manufacturing process. It may also represent a mechanism + that holds any other mechanism in place within a piece of equipment. + + + + + + + programmatic code being executed. **DEPRECATED** in *Version 1.1*. + + + + + + + operating state of a mechanism represented by a + {{block(Composition)}} entity. + + + + + + + current mode of the {{block(Controller)}} component. + + + + + + + setting or operator selection that changes the behavior of a piece + of equipment. + + + + + + + set of associated axes. + + + + + + + time and date code associated with a material or other physical + item. + + + + + + + identifier of another piece of equipment that is temporarily + associated with a component of this piece of equipment to perform a + particular function. + + + + + + + direction of motion. + + + + + + + operational state of a {{block(Door)}} component or composition + element. + + + + + + + state of the emergency stop signal for a piece of equipment, + controller path, or any other component or subsystem of a piece of + equipment. + + + + + + + indication of whether the end of a piece of bar stock being feed by + a bar feeder has been reached. + + + + + + + indication that a piece of equipment, or a sub-part of a piece of + equipment, is performing specific types of activities. + + + + + + + operating state of a {{block(Component)}}. + + + + + + + current intended production status of the {{block(Component)}}. + + + + + + + hardness of a material. + + + + + + + current line of code being executed. **DEPRECATED** in *Version + 1.4.0*. + + + + + + + identifier for a {{block(Block)}} of code in a {{block(Program)}}. + + + + + + + position of a block of program code within a control program. + + + + + + + identifier of a material used or consumed in the manufacturing + process. + + + + + + + identifies the layers of material applied to a part or product as + part of an additive manufacturing process. + + + + + + + information to be transferred from a piece of equipment to a client + software application. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + identifier for a pallet. + + + + + + + aggregate count of parts. + + + + + + + indication designating whether a part or work piece has been + detected or is present. + + + + + + + identifier of a part in a manufacturing operation. + + + + + + + identifier of a part or product moving through the manufacturing + process. **DEPRECATED** in *Version 1.7*. `PART_NUMBER` is now a + `subType` of `PART_KIND_ID`. + + + + + + + value of a signal or calculation issued to adjust the feedrate for + the axes associated with a {{block(Path)}} component that may + represent a single axis or the coordinated movement of multiple + axes. + + + + + + + describes the operational relationship between a {{block(Path)}} + entity and another {{block(Path)}} entity for pieces of equipment + comprised of multiple logical groupings of controlled axes or other + logical operations. + + + + + + + indication of the status of the source of energy for an entity to + allow it to perform its intended function or the state of an + enabling signal providing permission for the entity to perform its + functions. + + + + + + + status of the {{block(Component)}}. **DEPRECATED** in *Version + 1.1.0*. + + + + + + + time and date associated with an activity or event. + + + + + + + name of the logic or motion program being executed by the + {{block(Controller)}} component. + + + + + + + comment or non-executable statement in the control program. + + + + + + + indication of the status of the {{block(Controller)}} components + program editing mode. A program may be edited while another is + executed. + + + + + + + name of the program being edited. This is used in conjunction with + {{block(ProgramEdit)}} when in `ACTIVE` state. + + + + + + + non-executable header section of the control program. + + + + + + + {{term(URI)}} for the source file associated with + {{block(Program)}}. + + + + + + + defines whether the logic or motion program defined by + {{block(Program)}} is being executed from the local memory of the + controller or from an outside source. + + + + + + + indication of the nesting level within a control program that is + associated with the code or instructions that is currently being + executed. + + + + + + + current operating mode for a {{block(Rotary)}} type axis. + + + + + + + percentage change to the velocity of the programmed velocity for a + {{block(Rotary)}} axis. + + + + + + + serial number associated with a {{block(Component)}}, + {{block(Asset)}}, or {{block(Device)}}. + + + + + + + indication of the status of the spindle for a piece of equipment + when power has been removed and it is free to rotate. + + + + + + + identifier of an individual tool asset. + + + + + + + identifier for the tool group associated with a specific tool. + Commonly used to designate spare tools. + + + + + + + identifier of the tool currently in use for a given `Path`. + **DEPRECATED** in *Version 1.2.0*. See `TOOL_ASSET_ID`. + + + + + + + identifier assigned by the {{block(Controller)}} component to a + cutting tool when in use by a piece of equipment. + + + + + + + reference to the tool offset variables applied to the active cutting + tool. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + data whose meaning may change over time due to changes in the + operation of a piece of equipment or the process being executed on + that piece of equipment. + + + + + + + indication of the reason that {{block(Execution)}} is reporting a + value of `WAIT`. + + + + + + + identifier for the type of wire used as the cutting mechanism in + Electrical Discharge Machining or similar processes. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. **DEPRECATION WARNING**: Recommend using + `FIXTURE_ID` instead. + + + + + + + reference to offset variables for a work piece or part. + + + + + + + Operating System (OS) of a {{block(Component)}}. + + + + + + + embedded software of a {{block(Component)}} . + + + + + + + application on a {{block(Component)}}. + + + + + + + software library on a {{block(Component)}} + + + + + + + hardware of a {{block(Component)}}. + + + + + + + network details of a {{block(Component)}}. + + + + + + + three space angular displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + three space linear displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + {{term(UUID)}} of new device added to an {{term(MTConnect Agent)}}. + + + + + + + {{term(UUID)}} of a device removed from an {{term(MTConnect + Agent)}}. + + + + + + + {{term(UUID)}} of the device whose {{term(metadata)}} has changed. + + + + + + + status of the connection between an {{term(adapter)}} and an + {{term(agent)}}. + + + + + + + originator’s software version of the {{term(adapter)}}. + + + + + + + {{term(URI)}} of the {{term(adapter)}}. + + + + + + + reference version of the MTConnect Standard supported by the + {{term(adapter)}}. + + + + + + + {{term(attachment)}} between a sensor and an entity. + + + + + + + state or condition of a part. + + + + + + + identifier of a process being executed by the device. + + + + + + + identifier given to link the individual occurrence to a group of + related occurrences, such as a process step in a process plan. + + + + + + + identifier given to link the individual occurrence to a class of + processes or process definition. + + + + + + + identifier given to a collection of individual parts. + + + + + + + identifier given to link the individual occurrence to a class of + parts, typically distinguished by a particular part design. + + + + + + + identifier given to a distinguishable, individual part. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. **DEPRECATION WARNING**. Recommend using + `CONTROL_LIMITS`. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. **DEPRECATION WARNING**. Recommend using + `SPECIFICATION_LIMITS`. + + + + + + + set of limits used to trigger warning or alarm indicators. + **DEPRECATION WARNING**. Recommend using `ALARM_LIMITS`. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, load materials, parts, or other items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, unload materials, parts, or other + items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, transfer materials, parts, or other + items from one location to another. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, activate or be performed. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, deactivate or cease. + + + + + + + accumulation of the number of times a cyclic function has attempted + to, or is planned to attempt to execute. + + + + + + + state of a valve is one of open, closed, or transitioning between + the states. + + + + + + + state or operating mode of a {{block(Lock)}}. + + + + + + + particular condition of the process occurrence at a specific time. + + + + + + + particular condition of the part occurrence at a specific time. + + + + + + + state of {{block(Component)}} or {{block(Composition)}} that + describes the automatic or manual operation of the entity. + + + + + + + {{term(data set)}} of the number of {{termplural(Asset)}} of a given + type for a {{term(Device)}}. + + + + + + + actions or activities to be performed in support of a piece of + equipment. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. + + + + + + + interpretation of `PART_COUNT`. + + + + + + + time provided by a timing device at a specific point in time. + + + + + + + name of the host computer supplying data. + + + + + + + number of the TCP/IP or UDP/IP port for the connection endpoint. + + + + + + + indication designating whether a leak has been detected. + + + + + + + present status of the battery. + + + + + + + {{term(UUID)}} of a {{term(feature)}}. {{cite(ISO 10303 AP + 242/239)}}. + + + + + + + detection result of a sensor. + + + + + + + {{block(Event)}} that represents a {{block(Component)}} where the + {{block(EntryDefinition)}} identifies the {{block(Component)}} and + the {{block(CellDefinition)}}s define the + {{block(Component)}}'s observed {{block(DataItem)}}s. + + + + + + + properties of each addressable work offset. + + + + + + + properties of each addressable tool offset. + + + + + + + assessing elements of a {{term(feature)}}. + + + + + + + {{term(UUID)}} of the {{term(characteristic)}}. + + + + + + + class of measurement being performed. {{cite(QIF 3:2018 Section + 6.3)}} + + + + + + + measurement based on the measurement type. + + + + + + + engineering units of the measurement. + + + + + + + pass/fail result of the measurement. + + + + + + + method used to compute {{term(standard uncertainty)}}. + + + + + + + {{term(uncertainty)}} specified by {{block(UncertaintyType)}}. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. + + + + + + + set of limits used to trigger warning or alarm indicators. + + + + + + + references the {{block(CuttingToolLifeCycle)}} + {{block(CuttingItem)}} index related to the + {{property(CuttingItem::indices)}} of the currently active cutting + tool edge. + + + + + + + structured information that allows the unambiguous determination of + an object for purposes of identification and location. {{cite(ISO + 19160-4:2017)}} + + + + + + + active energy source for the {{block(Component)}}. + + + + + + + textual description of the location of an object or activity. + + + + + + + dimension between two surfaces of an object, usually the dimension + of smallest measure, for example an additive layer, or a depth of + cut. + + + + + + + absolute geographic location defined by two coordinates, longitude + and latitude and an elevation. + + + + + + + indication that the piece of equipment has experienced a + communications failure. + + + + + + + indication that the value of the data associated with a measured + value or a calculation is outside of an expected range. + + + + + + + indication that an error occurred in the logic program or + programmable logic controller (PLC) associated with a piece of + equipment. + + + + + + + indication that an error occurred in the motion program associated + with a piece of equipment. + + + + + + + general purpose indication associated with an electronic component + of a piece of equipment or a controller that represents a fault that + is not associated with the operator, program, or hardware. + + + + + + + indication of a fault associated with an actuator. + + + + + + + operational state of an {{block(Interface)}}. + + + + + + + operating state of the service to advance material or feed product + to a piece of equipment from a continuous or bulk source. + + + + + + + operating state of the service to change the type of material or + product being loaded or fed to a piece of equipment. + + + + + + + operating state of the service to remove or retract material or + product. + + + + + + + operating state of the service to change the part or product + associated with a piece of equipment to a different part or product. + + + + + + + operating state of the service to load a piece of material or + product. + + + + + + + operating state of the service to unload a piece of material or + product. + + + + + + + operating state of the service to open a chuck. + + + + + + + operating state of the service to open a door. + + + + + + + operating state of the service to close a chuck. + + + + + + + operating state of the service to close a door. + + + + + + + A user variable + + + + + + + + + The types of measurements available + + + + + + + + Extended tyoe for The sub-types for a measurement + + + + + + + + + + The sub-types for a measurement + + + + + + + relating to or derived in the simplest manner from the fundamental + units or measurements. + + + + + + + indication of the operating state of a mechanism. + + + + + + + measured or reported value of an {{term(observation)}}. + + + + + + + all actions, items, or activities being counted independent of the + outcome. + + + + + + + measurement of alternating voltage or current. If not specified + further in statistic, defaults to RMS voltage. **DEPRECATED** in + *Version 1.6*. + + + + + + + A-Scale weighting factor on the frequency scale. + + + + + + + when multiple locations on a piece of bar stock being feed by a bar + feeder are referenced as the indication of whether the end of that + piece of bar stock has been reached. + + + + + + + actions, items, or activities being counted that do not conform to + specification or expectation. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + B-Scale weighting factor on the frequency scale. + + + + + + + directive value including adjustments such as an offset or + overrides. + + + + + + + amount of material consumed from an object or container during a + manufacturing process. + + + + + + + state of the enabling signal or control logic that enables or + disables the function or operation of the entity. + + + + + + + C-Scale weighting factor on the frequency scale. + + + + + + + elapsed time of a temporary halt of action. + + + + + + + DC current or voltage. **DEPRECATED** in *Version 1.6*. + + + + + + + setting or operator selection used to execute a test mode to confirm + the execution of machine functions. + + + + + + + D-Scale weighting factor on the frequency scale. + + + + + + + relating to the expiration or end of useful life for a material or + other physical item. + + + + + + + relating to the first use of a material or other physical item. + + + + + + + actions, items, or activities being counted that conform to + specification or expectation. + + + + + + + relating to or derived from the last {{term(observation)}}. + + + + + + + relating to momentary activation of a function or a movement. + **DEPRECATION WARNING**: May be deprecated in the future. + + + + + + + indication of the position of a mechanism that may move in a lateral + direction. + + + + + + + scale to measure the elasticity of a surface. + + + + + + + reference to a length type tool offset variable. + + + + + + + state of the power source. + + + + + + + direction of motion of a linear motion. + + + + + + + indication that the subparts of a piece of equipment are under load. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + relating to the primary logic or motion program currently being + executed. + + + + + + + relating to maintenance on the piece of equipment. + + + + + + + indication of the state of an operator controlled interlock that can + inhibit the ability to initiate an unclamp action of an + electronically controlled chuck. + + + + + + + related to the production of a material or other physical item. + + + + + + + maximum value. + + + + + + + minimum value. + + + + + + + scale to measure the resistance to scratching of a surface. + + + + + + + indication of the open or closed state of a mechanism. + + + + + + + no weighting factor on the frequency scale. + + + + + + + piece of equipment that is powered or performing any activity. + + + + + + + relating to the person currently responsible for operating the piece + of equipment. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + overridden value. + + + + + + + piece of equipment is powered and functioning or + {{block(Component)}} that are required to remain on are powered. + + + + + + + main or principle. + + + + + + + position provided by a measurement probe. **DEPRECATION WARNING**: + May be deprecated in the future. + + + + + + + relating to production of a part or product on a piece of equipment. + + + + + + + directive value without offsets and adjustments. + + + + + + + reference to a radial type tool offset variable. + + + + + + + performing an operation faster or in less time than nominal rate. + + + + + + + remaining measure or count of an action, object or activity. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + direction of a rotary motion using the right hand rule convention. + + + + + + + identity of a control program that is used to specify the order of + execution of other programs. + + + + + + + relating to the preparation of a piece of equipment for production + or restoring the piece of equipment to a neutral state after + production. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + standard measure of an object or an action. + + + + + + + boundary when an activity or an event commences. + + + + + + + indication of the activation state of a mechanism represented by a + {{block(Composition)}}. + + + + + + + goal of the operation or process. + + + + + + + relating to the end or completion of an activity or event. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + remaining usable measure of an object or action. + + + + + + + indication of the position of a mechanism that may move in a + vertical direction. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + piece of equipment performing any activity, the equipment is active + and performing a function under load or not. + + + + + + + IPV4 network address of the {{block(Component)}}. + + + + + + + IPV6 network address of the {{block(Component)}}. + + + + + + + Gateway for the {{block(Component)}} network. + + + + + + + SubNet mask for the {{block(Component)}} network. + + + + + + + layer2 Virtual Local Network (VLAN) ID for the {{block(Component)}} + network. + + + + + + + Media Access Control Address. The unique physical address of the + network hardware. + + + + + + + identifies whether the connection type is wireless. + + + + + + + license code to validate or activate the hardware or software. + + + + + + + version of the hardware or software. + + + + + + + date the hardware or software was released for general use. + + + + + + + date the hardware or software was installed. + + + + + + + corporate identity for the maker of the hardware or software. + + + + + + + universally unique identifier as specified in ISO 11578 or RFC 4122. + + + + + + + serial number that uniquely identifies a specific part. + + + + + + + material that is used to produce parts. + + + + + + + group of parts tracked as a lot. + + + + + + + group of parts produced in a batch. + + + + + + + material heat number. + + + + + + + particular part design or model. + + + + + + + group of parts having similarities in geometry, manufacturing + process, and/or functions. + + + + + + + word or set of words by which a part is known, addressed, or + referred to. + + + + + + + step in the process plan that this occurrence corresponds to. + + + + + + + process plan that a process occurrence belongs to. + + + + + + + authorization of a process occurrence. + + + + + + + word or set of words by which a process being executed (process + occurrence) by the device is known, addressed, or referred to. + + + + + + + reference to a ISO 10303 Executable. + + + + + + + associated with the completion of an activity or event. + + + + + + + relating to logic or motion program currently executing. + + + + + + + actions or activities that were attempted , but failed to complete + or resulted in an unexpected or unacceptable outcome. + + + + + + + actions or activities that were attempted, but terminated before + they could be completed. + + + + + + + boundary when an activity or an event terminates. + + + + + + + amount discarded. + + + + + + + amount included in the {{term(part)}}. + + + + + + + {{term(request)}} by an {{block(Interface)}} for a task. + + + + + + + {{term(response)}} by an {{block(Interface)}} to a {{term(request)}} + for a task. + + + + + + + phase or segment of a recipe or program. + + + + + + + phase of a recipe process. + + + + + + + process as part of product production; can be a subprocess of a + larger process. + + + + + + + step of a discrete manufacturing process. + + + + + + + observed as a binary data type. + + + + + + + observed as a boolean data type. + + + + + + + observed as a set containing a restricted number of discrete values + where each discrete value is named and unique. {{cite(ISO + 21961:2003, 013)}} + + + + + + + indicated by the presence or existence of something. + + + + + + + model info of the hardware or software. + + + + + + + + + The sub-types for a measurement + + + + + + + + Extended tyoe for Statistical operations on data + + + + + + + + + + Statistical operations on data + + + + + + + mathematical average value calculated for the data item during the + calculation period. + + + + + + + **DEPRECATED** in *Version 1.6*. ~~A measure of the + "peakedness" of a probability distribution; i.e., the + shape of the distribution curve.~~ + + + + + + + maximum or peak value recorded for the data item during the + calculation period. + + + + + + + middle number of a series of numbers. + + + + + + + minimum value recorded for the data item during the calculation + period. + + + + + + + number in a series of numbers that occurs most often. + + + + + + + difference between the maximum and minimum value of a data item + during the calculation period. Also represents Peak-to-Peak + measurement in a waveform. + + + + + + + mathematical Root Mean Square (RMS) value calculated for the data + item during the calculation period. + + + + + + + statistical Standard Deviation value calculated for the data item + during the calculation period. + + + + + + + + + Statistical operations on data + + + + + + + + Extended tyoe for same as {{property(DataItem::units)}}. See + {{package(Device Information Model)}}. + + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + + Extended tyoe for The units supported for the source equipment that can + be converted into MTC Units. + + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + measure of viscosity. + + + + + + + rotational velocity in degrees per minute. + + + + + + + temperature in Fahrenheit. + + + + + + + feet. + + + + + + + feet per minute. + + + + + + + feet per second. + + + + + + + acceleration in feet per second squared. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in feet. + + + + + + + gallons per minute. + + + + + + + measurement of time in hours. + + + + + + + inches. + + + + + + + inches per minute. + + + + + + + inches per second. + + + + + + + acceleration in inches per second squared. + + + + + + + measure of torque in inch pounds. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in inches. + + + + + + + measurement of temperature. + + + + + + + measurement in kilowatt. + + + + + + + kilowatt hours which is 3.6 mega joules. + + + + + + + measurement of rate of flow of a fluid. + + + + + + + velocity in millimeters per minute. + + + + + + + measurement of time in minutes. + + + + + + + unsupported unit. + + + + + + + US pounds. + + + + + + + pressure in pounds per square inch (PSI). + + + + + + + angle in radians. + + + + + + + velocity in radians per minute. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + pressure in Bar. + + + + + + + pressure in Torr. + + + + + + + pressure in Millimeter of Mercury (mmHg). + + + + + + + pascal per minute. + + + + + + + $$MASS\times GRAVITATIONAL_ACCELERATION$$ (g) given in + `METER/SECOND^2`. + + + + + + + acceleration relative to earth's gravity given in + `METER/SECOND^2`. > Note 1 to entry: At different points on + Earth's surface, the free-fall acceleration ranges from 9.764 + to 9.834 m/s2 (Wikipedia: Gravitational Acceleration). The constant + can be customized depending on the location in the universe. > + Note 2 to entry: In the standard, it is assumed that Earth's + average value of gravitational acceleration is 9.90665 m/s2. + + + + + + + electric charge in ampere hour. + + + + + + + change of geometric volume in cubic foot per hour. + + + + + + + change of geometric volume in cubic foot per minute. + + + + + + + geometric area in inches. + + + + + + + geometric volume in feet. + + + + + + + inch per revolution. + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + + The coordinate system to be used for the position + + + + + + + unchangeable coordinate system that has machine zero as its origin. + + + + + + + coordinate system that represents the working area for a particular + workpiece whose origin is shifted within the `MACHINE` coordinate + system. If the `WORK` coordinates are not currently defined in the + piece of equipment, the `MACHINE` coordinates will be used. + + + + + + + + + Extended tyoe for The reset intervals + + + + + + + + + + The reset intervals + + + + + + + {{term(observation)}} of the {{block(DataItem)}} that is measuring + an action or operation is to be reset upon completion of that action + or operation. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 12-month period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 24-hour period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is not reset and + accumulates for the entire life of the piece of equipment. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset upon + completion of a maintenance event. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a monthly period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset when + power was applied to the piece of equipment after a planned or + unplanned interruption of power has occurred. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a work shift. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 7-day period. + + + + + + + + + The reset intervals + + + + + + + + + The document version + + + + + + + time the file was created. + + + + + + + Indicates that this was a test document + + + + + + + The unique instance identifier of this agent process + + + + + + + The sender of the message + + + + + + + A timestamp in 8601 format of the last update of the Device + information for any device + + + + + + + + The station id for this device + + + + + + + + indicates if the MTConnect Agent is validating against the normative + model. + + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the data + management within the {{term(agent)}}. + + + + + + + + + The size of the agent's buffer. + + + + + + + The next sequence number for subsequent requests + + + + + + + The last sequence number available from the agent + + + + + + + The first sequence number available from the agent + + + + + + + indicates if the MTConnect Agent is validating against the + normative model. + + + + + + + + + + root entity of an {{term(MTConnectStreams Response Document)}} that + contains the {{term(Observation Information Model)}} of one or more + {{block(Device)}} entities. + ![MTConnectStreams](figures/MTConnectStreams.png + "MTConnectStreams"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectStreams)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the + data management within the {{term(agent)}}. + + + + + + + {{block(Streams)}} groups one or more {{block(DeviceStream)}} + entities. See {{package(Observation Information Model)}} for more + detail. + + + + + + + + + An events data + + + + + + + + The item's unique ID that references the data item id from probe + + + + + + + + An Condition code as defined by the component + + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been deprecated in the MTConnect Standard. + + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been extended and cannot be validated. + + + + + + + + indicates if the Observation is verifiable and is in accordance with the + normative definitions within the MTConnect Standard. + + + + + + + observation is not valid against the MTConnect Standard according to + the validation capabilities of the MTConnect Agent. + + + + + + + observation cannot be validated. + + + + + + + observation is valid against the MTConnect Standard. + + + + + + + + + {{block(Streams)}} groups one or more {{block(DeviceStream)}} entities. + See {{package(Observation Information Model)}} for more detail. + + + + + + + Description + + + + + + + + + Description + + + + + + + {{block(ComponentStream)}} {{termplural(organize)}} the + {{block(Observation)}} entities associated with the + {{block(Component)}}. See {{package(Observation Information Model)}} + for the {{block(ComponentStream)}} model. > Note 1 to entry: In + the {{term(XML)}} representation, {{block(ComponentStream)}} + entities **MUST NOT** appear in the {{term(MTConnectDevices Response + Document)}}. > Note 2 to entry: In the {{term(XML)}} + representation, {{block(ComponentStream)}} entities **MUST** appear + only in the {{term(MTConnectStreams Response Document)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + The unque identifier for this device + + + + + + + + {{block(ComponentStream)}} {{termplural(organize)}} the + {{block(Observation)}} entities associated with the + {{block(Component)}}. See {{package(Observation Information Model)}} for + the {{block(ComponentStream)}} model. > Note 1 to entry: In the + {{term(XML)}} representation, {{block(ComponentStream)}} entities **MUST + NOT** appear in the {{term(MTConnectDevices Response Document)}}. > + Note 2 to entry: In the {{term(XML)}} representation, + {{block(ComponentStream)}} entities **MUST** appear only in the + {{term(MTConnectStreams Response Document)}}. + + + + + + + {{block(Samples)}} groups one or more {{block(Sample)}} entities. + See {{sect(Sample)}}. + + + + + + + {{block(Events)}} groups one or more {{block(Event)}} entities. See + {{sect(Event)}}. + + + + + + + Description + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + identifier of the maintenance activity. + + + + + + + The device manufacturer component name + + + + + + + Description + + + + + + + The unque identifier for this component + + + + + + + + {{block(Samples)}} groups one or more {{block(Sample)}} entities. See + {{sect(Sample)}}. + + + + + + + + + + {{block(Events)}} groups one or more {{block(Event)}} entities. See + {{sect(Event)}}. + + + + + + + + + + A collection of conditions + + + + + + + + + + The observation value for indeterminent data + + + + + + + Data is unavailable + + + + + + + + + + The events sequence number + + + + + + + The event subtype corresponding to the measurement subtype + + + + + + + The time the event occurred or recorded + + + + + + + identifier of the maintenance activity. + + + + + + + The unique identifier of the item being produced + + + + + + + The identifier of the sub-element this result is in reference to + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been deprecated in the MTConnect Standard. + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been extended and cannot be validated. + + + + + + + indicates if the Observation is verifiable and is in accordance with + the normative definitions within the MTConnect Standard. + + + + + + + + The target rate a value can be sampled + + + + + + + + The number of items in the list + + + + + + + + Common floating point sample value + + + + + + + + Common floating point sample value + + + + + + + + Description + + + + + + + The rate the waveform was sampled at, default back to the value given + in the data item + + + + + + + An optional indicator that the event or sample was reset + + + + + + + The statistical operation on this data + + + + + + + The number of seconds since the reset of the statistic + + + + + + + + Description + + + + + + + A sample with a single floating point value + + + + + + + + + + + + + + A sample with a single floating point value + + + + + + + A sample with a three tuple floating point value + + + + + + + + + + + + + + A sample with a three tuple floating point value + + + + + + + The abstract waveform + + + + + + + + The number of samples + + + + + + + + + + The abstract waveform + + + + + + + Description + + + + + + + + + + + + + + Description + + + + + + + {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ACCELERATION)}} + + + + + + + {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + Time series of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + Time series of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE)}} + + + + + + + {{def(SampleEnum::ANGLE)}} + + + + + + + + + + {{def(SampleEnum::ANGLE)}} + + + + + + + Time series of {{def(SampleEnum::ANGLE)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGLE)}} + + + + + + + {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + Time series of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + Time series of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + Time series of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + Time series of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + Time series of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + {{def(SampleEnum::CONCENTRATION)}} + + + + + + + Time series of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + Time series of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + Time series of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + Time series of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + {{def(SampleEnum::DENSITY)}} + + + + + + + + + + {{def(SampleEnum::DENSITY)}} + + + + + + + Time series of {{def(SampleEnum::DENSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::DENSITY)}} + + + + + + + {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + Time series of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + Time series of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + Time series of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + {{def(SampleEnum::FLOW)}} + + + + + + + + + + {{def(SampleEnum::FLOW)}} + + + + + + + Time series of {{def(SampleEnum::FLOW)}} + + + + + + + + + + Time series of {{def(SampleEnum::FLOW)}} + + + + + + + {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + {{def(SampleEnum::FREQUENCY)}} + + + + + + + Time series of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + Time series of {{def(SampleEnum::FREQUENCY)}} + + + + + + + {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + Time series of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + Time series of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + {{def(SampleEnum::LENGTH)}} + + + + + + + + + + {{def(SampleEnum::LENGTH)}} + + + + + + + Time series of {{def(SampleEnum::LENGTH)}} + + + + + + + + + + Time series of {{def(SampleEnum::LENGTH)}} + + + + + + + {{def(SampleEnum::LEVEL)}} + + + + + + + + + + {{def(SampleEnum::LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::LEVEL)}} + + + + + + + {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + Time series of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + Time series of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + {{def(SampleEnum::LOAD)}} + + + + + + + + + + {{def(SampleEnum::LOAD)}} + + + + + + + Time series of {{def(SampleEnum::LOAD)}} + + + + + + + + + + Time series of {{def(SampleEnum::LOAD)}} + + + + + + + {{def(SampleEnum::MASS)}} + + + + + + + + + + {{def(SampleEnum::MASS)}} + + + + + + + Time series of {{def(SampleEnum::MASS)}} + + + + + + + + + + Time series of {{def(SampleEnum::MASS)}} + + + + + + + {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Example + + + + + + + + + + Example + + + + + + + {{def(SampleEnum::PH)}} + + + + + + + + + + {{def(SampleEnum::PH)}} + + + + + + + Time series of {{def(SampleEnum::PH)}} + + + + + + + + + + Time series of {{def(SampleEnum::PH)}} + + + + + + + {{def(SampleEnum::POSITION)}} + + + + + + + + + + {{def(SampleEnum::POSITION)}} + + + + + + + Time series of {{def(SampleEnum::POSITION)}} + + + + + + + + + + Time series of {{def(SampleEnum::POSITION)}} + + + + + + + {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Time series of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + Time series of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Description + + + + + + + + + + Description + + + + + + + Time series of {{def(SampleEnum::PRESSURE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PRESSURE)}} + + + + + + + {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + Time series of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + Time series of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + {{def(SampleEnum::RESISTANCE)}} + + + + + + + Time series of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + Time series of {{def(SampleEnum::RESISTANCE)}} + + + + + + + {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + Time series of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + Time series of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + {{def(SampleEnum::STRAIN)}} + + + + + + + + + + {{def(SampleEnum::STRAIN)}} + + + + + + + Time series of {{def(SampleEnum::STRAIN)}} + + + + + + + + + + Time series of {{def(SampleEnum::STRAIN)}} + + + + + + + {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + {{def(SampleEnum::TEMPERATURE)}} + + + + + + + Time series of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + Time series of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + {{def(SampleEnum::TENSION)}} + + + + + + + + + + {{def(SampleEnum::TENSION)}} + + + + + + + Time series of {{def(SampleEnum::TENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::TENSION)}} + + + + + + + {{def(SampleEnum::TILT)}} + + + + + + + + + + {{def(SampleEnum::TILT)}} + + + + + + + Time series of {{def(SampleEnum::TILT)}} + + + + + + + + + + Time series of {{def(SampleEnum::TILT)}} + + + + + + + {{def(SampleEnum::TORQUE)}} + + + + + + + + + + {{def(SampleEnum::TORQUE)}} + + + + + + + Time series of {{def(SampleEnum::TORQUE)}} + + + + + + + + + + Time series of {{def(SampleEnum::TORQUE)}} + + + + + + + {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::VELOCITY)}} + + + + + + + {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + {{def(SampleEnum::VISCOSITY)}} + + + + + + + Time series of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::VISCOSITY)}} + + + + + + + {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE)}} + + + + + + + {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + Time series of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + Time series of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + {{def(SampleEnum::WATTAGE)}} + + + + + + + Time series of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::WATTAGE)}} + + + + + + + {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::X_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + {{def(SampleEnum::DIAMETER)}} + + + + + + + Time series of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + Time series of {{def(SampleEnum::DIAMETER)}} + + + + + + + {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + + {{def(SampleEnum::ORIENTATION)}} + + + + + + + {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + Time series of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + {{def(SampleEnum::DECELERATION)}} + + + + + + + Time series of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::DECELERATION)}} + + + + + + + {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + The force per unit area measured relative to a vacuum. + + + + + + + + + + The force per unit area measured relative to a vacuum. + + + + + + + Time series of The force per unit area measured relative to a vacuum. + + + + + + + + + + Time series of The force per unit area measured relative to a vacuum. + + + + + + + {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + {{def(SampleEnum::OPENNESS)}} + + + + + + + Time series of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + Time series of {{def(SampleEnum::OPENNESS)}} + + + + + + + {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + {{def(SampleEnum::DEW_POINT)}} + + + + + + + Time series of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEW_POINT)}} + + + + + + + {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + + + + {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + Time series of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + Time series of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + + {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + Integer event value + + + + + + + + Integer event value + + + + + + + + String event value + + + + + + + + DateTime String event value + + + + + + + + A list of axis names + + + + + + + + + + + + A list of axis for an event + + + + + + + + Common floating point event value + + + + + + + + Description + + + + + + + An optional indicator that the event or sample was reset + + + + + + + + Description + + + + + + + An unfaceted string event + + + + + + + + + + + + + + An unfaceted string event + + + + + + + An unfaceted string event + + + + + + + + + + + + + + An unfaceted string event + + + + + + + An unfaceted datetime event + + + + + + + + + + + + + + An unfaceted datetime event + + + + + + + An event with an integer value + + + + + + + + + + + + + + An event with an integer value + + + + + + + An event with an integer value + + + + + + + + + + + + + + An event with an integer value + + + + + + + An event with a three tuple floating point value + + + + + + + + + + + + + + An event with a three tuple floating point value + + + + + + + {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + + {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + Controlled vocabulary for ActuatorState + + + + + + + {{block(Actuator)}} is operating. + + + + + + + {{block(Actuator)}} is not operating. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + The type of asset + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + The type of asset + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + Controlled vocabulary for Availability + + + + + + + data source is active and capable of providing data. + + + + + + + data source is either inactive or not capable of providing data. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + + + + + + {{def(EventEnum::AVAILABILITY)}} + + + + + + + Controlled vocabulary for AxisCoupling + + + + + + + axes are physically connected to each other and operate as a single + unit. + + + + + + + axes are not physically connected to each other but are operating + together in lockstep. + + + + + + + axis is the master of the {{block(CoupledAxes)}}. + + + + + + + axis is a slave to the {{block(CoupledAxes)}}. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + + {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + Controlled vocabulary for AxisInterlock + + + + + + + axis lockout function is activated, power has been removed from the + axis, and the axis is allowed to move freely. + + + + + + + axis lockout function has not been activated, the axis may be + powered, and the axis is capable of being controlled by another + component. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + Controlled vocabulary for AxisState + + + + + + + axis is in its home position. + + + + + + + axis is in motion. + + + + + + + axis has been moved to a fixed position and is being maintained in + that position either electrically or mechanically. Action is + required to release the axis from this position. + + + + + + + axis is stopped. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_STATE)}} + + + + + + + {{def(EventEnum::BLOCK)}} + + + + + + + + + + {{def(EventEnum::BLOCK)}} + + + + + + + {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + + {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + Controlled vocabulary for ChuckInterlock + + + + + + + chuck cannot be unclamped. + + + + + + + chuck can be unclamped. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + Controlled vocabulary for ChuckState + + + + + + + {{block(Chuck)}} is open to the point of a positive confirmation. + + + + + + + {{block(Chuck)}} is closed to the point of a positive confirmation. + + + + + + + {{block(Chuck)}} is not closed to the point of a positive + confirmation and not open to the point of a positive confirmation. + It is in an intermediate position. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::CHUCK_STATE)}} + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + + {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + Controlled vocabulary for ControllerMode + + + + + + + {{block(Controller)}} is configured to automatically execute a + program. + + + + + + + {{block(Controller)}} is not executing an active program. It is + capable of receiving instructions from an external source – + typically an operator. The {{block(Controller)}} executes operations + based on the instructions received from the external source. + + + + + + + operator can enter a series of operations for the + {{block(Controller)}} to perform. The {{block(Controller)}} will + execute this specific series of operations and then stop. + + + + + + + {{block(Controller)}} is operating in a mode that restricts the + active program from processing its next process step without + operator intervention. + + + + + + + {{block(Controller)}} is currently functioning as a programming + device and is not capable of executing an active program. + + + + + + + axes of the device are commanded to stop, but the spindle continues + to function. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + Controlled vocabulary for ControllerModeOverride + + + + + + + {{block(ControllerModeOverride)}} is in the `ON` state and the mode + override is active. + + + + + + + {{block(ControllerModeOverride)}} is in the `OFF` state and the mode + override is inactive. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + + {{def(EventEnum::COUPLED_AXES)}} + + + + + + + {{def(EventEnum::DATE_CODE)}} + + + + + + + + + + {{def(EventEnum::DATE_CODE)}} + + + + + + + {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + + {{def(EventEnum::DEVICE_UUID)}} + + + + + + + Controlled vocabulary for Direction + + + + + + + clockwise rotation using the right-hand rule. + + + + + + + counter-clockwise rotation using the right-hand rule. + + + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::DIRECTION)}} + + + + + + + + + + + + + + {{def(EventEnum::DIRECTION)}} + + + + + + + Controlled vocabulary for DoorState + + + + + + + {{block(Door)}} is open to the point of a positive confirmation. + + + + + + + {{block(Door)}} is closed to the point of a positive confirmation. + + + + + + + {{block(Door)}} is not closed to the point of a positive + confirmation and not open to the point of a positive confirmation. + It is in an intermediate position. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::DOOR_STATE)}} + + + + + + + Controlled vocabulary for EmergencyStop + + + + + + + emergency stop circuit is complete and the piece of equipment, + component, or composition is allowed to operate. + + + + + + + operation of the piece of equipment, component, or composition is + inhibited. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + + + + + + {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + Controlled vocabulary for EndOfBar + + + + + + + {{block(EndOfBar)}} has been reached. + + + + + + + {{block(EndOfBar)}} has not been reached. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + + + + + + {{def(EventEnum::END_OF_BAR)}} + + + + + + + Controlled vocabulary for EquipmentMode + + + + + + + equipment is functioning in the mode designated by the `subType`. + + + + + + + equipment is not functioning in the mode designated by the + `subType`. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + Controlled vocabulary for Execution + + + + + + + {{block(Component)}} is ready to execute instructions. It is + currently idle. + + + + + + + {{block(Component)}} is actively executing an instruction. + + + + + + + {{block(Component)}} suspends the execution of the program due to an + external signal. Action is required to resume execution. + + + + + + + motion of the active axes are commanded to stop at their current + position. + + + + + + + {{block(Component)}} program is not `READY` to execute. + + + + + + + command from the program has intentionally interrupted execution. + The {{block(Component)}} **MAY** have another state that indicates + if the execution is interrupted or the execution ignores the + interrupt instruction. + + + + + + + command from the program has intentionally interrupted execution. + Action is required to resume execution. + + + + + + + program completed execution. + + + + + + + {{block(Component)}} suspends execution while a secondary operation + executes. Execution resumes automatically once the secondary + operation completes. + + + + + + + program has been intentionally optionally stopped using an M01 or + similar code. **DEPRECATED** in *version 1.4* and replaced with + `OPTIONAL_STOP`. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EXECUTION)}} + + + + + + + + + + + + + + {{def(EventEnum::EXECUTION)}} + + + + + + + Controlled vocabulary for FunctionalMode + + + + + + + {{block(Component)}} is currently producing product, ready to + produce product, or its current intended use is to be producing + product. + + + + + + + {{block(Component)}} is not currently producing product. It is being + prepared or modified to begin production of product. + + + + + + + {{block(Component)}} is not currently producing product. Typically, + it has completed the production of a product and is being modified + or returned to a neutral state such that it may then be prepared to + begin production of a different product. + + + + + + + {{block(Component)}} is not currently producing product. It is + currently being repaired, waiting to be repaired, or has not yet + been returned to a normal production status after maintenance has + been performed. + + + + + + + {{block(Component)}} is being used to prove-out a new process, + testing of equipment or processes, or any other active use that does + not result in the production of product. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + {{def(EventEnum::HARDNESS)}} + + + + + + + + + + {{def(EventEnum::HARDNESS)}} + + + + + + + {{def(EventEnum::LINE)}} + + + + + + + + + + {{def(EventEnum::LINE)}} + + + + + + + {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + + {{def(EventEnum::LINE_LABEL)}} + + + + + + + {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + + {{def(EventEnum::LINE_NUMBER)}} + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + + {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + {{def(EventEnum::MESSAGE)}} + + + + + + + + + + {{def(EventEnum::MESSAGE)}} + + + + + + + {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + + {{def(EventEnum::OPERATOR_ID)}} + + + + + + + {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + {{def(EventEnum::PALLET_ID)}} + + + + + + + {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + {{def(EventEnum::PART_COUNT)}} + + + + + + + Controlled vocabulary for PartDetect + + + + + + + part or work piece is detected or is present. + + + + + + + part or work piece is not detected or is not present. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_DETECT)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_DETECT)}} + + + + + + + {{def(EventEnum::PART_ID)}} + + + + + + + + + + {{def(EventEnum::PART_ID)}} + + + + + + + {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + + {{def(EventEnum::PART_NUMBER)}} + + + + + + + {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + + {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + Controlled vocabulary for PathMode + + + + + + + path is operating independently and without the influence of another + path. + + + + + + + path provides information or state values that influences the + operation of other {{block(DataItem)}} of similar type. + + + + + + + physical or logical parts which are not physically connected to each + other but are operating together. + + + + + + + axes associated with the path are mirroring the motion of the + `MASTER` path. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PATH_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::PATH_MODE)}} + + + + + + + Controlled vocabulary for PowerState + + + + + + + source of energy for an entity or the enabling signal providing + permission for the entity to perform its function(s) is present and + active. + + + + + + + source of energy for an entity or the enabling signal providing + permission for the entity to perform its function(s) is not present + or is disconnected. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::POWER_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::POWER_STATE)}} + + + + + + + Controlled vocabulary for PowerStatus + + + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::POWER_STATUS)}} + + + + + + + {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + + {{def(EventEnum::PROCESS_TIME)}} + + + + + + + {{def(EventEnum::PROGRAM)}} + + + + + + + + + + {{def(EventEnum::PROGRAM)}} + + + + + + + {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + Controlled vocabulary for ProgramEdit + + + + + + + {{block(Controller)}} is in the program edit mode. + + + + + + + {{block(Controller)}} is capable of entering the program edit mode + and no function is inhibiting a change to that mode. + + + + + + + {{block(Controller)}} is being inhibited by a function from entering + the program edit mode. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + Controlled vocabulary for ProgramLocationType + + + + + + + managed by the controller. + + + + + + + not managed by the controller. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is not + defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + + {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is not + defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + Controlled vocabulary for RotaryMode + + + + + + + axis is functioning as a spindle. + + + + + + + axis is configured to index. + + + + + + + position of the axis is being interpolated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::ROTARY_MODE)}} + + + + + + + {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command represents a + percentage change to the velocity calculated by a logic or motion + program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + + {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command represents a + percentage change to the velocity calculated by a logic or motion + program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + Controlled vocabulary for SpindleInterlock + + + + + + + power has been removed and the spindle cannot be operated. + + + + + + + spindle has not been deactivated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + + {{def(EventEnum::TOOL_GROUP)}} + + + + + + + {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + {{def(EventEnum::TOOL_ID)}} + + + + + + + {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + + {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + {{def(EventEnum::USER)}} + + + + + + + + + + {{def(EventEnum::USER)}} + + + + + + + {{def(EventEnum::VARIABLE)}} + + + + + + + + + + {{def(EventEnum::VARIABLE)}} + + + + + + + Controlled vocabulary for WaitState + + + + + + + execution is waiting while the equipment is powering up and is not + currently available to begin producing parts or products. + + + + + + + execution is waiting while the equipment is powering down but has + not fully reached a stopped state. + + + + + + + execution is waiting while one or more discrete workpieces are being + loaded. + + + + + + + execution is waiting while one or more discrete workpieces are being + unloaded. + + + + + + + execution is waiting while a tool or tooling is being loaded. + + + + + + + execution is waiting while a tool or tooling is being unloaded. + + + + + + + execution is waiting while material is being loaded. + + + + + + + execution is waiting while material is being unloaded. + + + + + + + execution is waiting while another process is completed before the + execution can resume. + + + + + + + execution is waiting while the equipment is pausing but the piece of + equipment has not yet reached a fully paused state. + + + + + + + execution is waiting while the equipment is resuming the production + cycle but has not yet resumed execution. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::WAIT_STATE)}} When {{property(Execution::result)}} is + not `WAIT`, {{property(Observation::isUnavailable)}} of + {{block(WaitState)}} **MUST** be `true`. + + + + + + + + + + + + + + {{def(EventEnum::WAIT_STATE)}} When {{property(Execution::result)}} is + not `WAIT`, {{property(Observation::isUnavailable)}} of + {{block(WaitState)}} **MUST** be `true`. + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + + {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + + {{def(EventEnum::WORK_OFFSET)}} + + + + + + + {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + + {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + {{def(EventEnum::FIRMWARE)}} + + + + + + + + + + {{def(EventEnum::FIRMWARE)}} + + + + + + + {{def(EventEnum::APPLICATION)}} + + + + + + + + + + {{def(EventEnum::APPLICATION)}} + + + + + + + {{def(EventEnum::LIBRARY)}} + + + + + + + + + + {{def(EventEnum::LIBRARY)}} + + + + + + + {{def(EventEnum::HARDWARE)}} + + + + + + + + + + {{def(EventEnum::HARDWARE)}} + + + + + + + {{def(EventEnum::NETWORK)}} + + + + + + + + + + {{def(EventEnum::NETWORK)}} + + + + + + + rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + + rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + + + + translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + Controlled vocabulary for PartStatus + + + + + + + part conforms to given requirements. + + + + + + + part does not conform to some given requirements. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_STATUS)}} If unique identifier is given, part + status is for that individual. If group identifier is given without a + unique identifier, then the status is assumed to be for the whole group. + + + + + + + + + + + + + + {{def(EventEnum::PART_STATUS)}} If unique identifier is given, part + status is for that individual. If group identifier is given without a + unique identifier, then the status is assumed to be for the whole group. + + + + + + + {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + + {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + {{def(EventEnum::PART_KIND_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_KIND_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + + {{def(EventEnum::ADAPTER_URI)}} + + + + + + + {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + + {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + Controlled vocabulary for ConnectionStatus + + + + + + + no connection at all. + + + + + + + {{term(agent)}} is waiting for a connection request from an + {{term(adapter)}}. + + + + + + + open connection. The normal state for the data transfer phase of the + connection. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + + {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + + {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + + {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + + {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + {{def(EventEnum::PART_GROUP_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_GROUP_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::PART_UNIQUE_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_UNIQUE_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + + {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + + {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + + {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + + {{def(EventEnum::LOAD_COUNT)}} + + + + + + + Controlled vocabulary for PartProcessingState + + + + + + + part occurrence is not actively being processed, but the processing + has not ended. Processing requirements exist that have not yet been + fulfilled. This is the default entry state when the part occurrence + is originally received. In some cases, the part occurrence may + return to this state while it waits for additional processing to be + performed. + + + + + + + part occurrence is actively being processed. + + + + + + + part occurrence is no longer being processed. A general state when + the reason for termination is unknown. + + + + + + + part occurrence has completed processing successfully. + + + + + + + process has been stopped during the processing. The part occurrence + will require special treatment. + + + + + + + processing of the part occurrence has come to a premature end. + + + + + + + terminal state when the part occurrence has been removed from the + equipment by an external entity and it no longer exists at the + equipment. + + + + + + + part occurrence has been skipped for processing on the piece of + equipment. + + + + + + + part occurrence has been processed completely. However, the + processing may have a problem. + + + + + + + part occurrence is waiting for transit. + + + + + + + part occurrence is being transported to its destination. + + + + + + + part occurrence has been placed at its designated destination. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + Controlled vocabulary for ProcessState + + + + + + + device is preparing to execute the process occurrence. + + + + + + + process occurrence is ready to be executed. + + + + + + + process occurrence is actively executing. + + + + + + + process occurrence is now finished. + + + + + + + process occurrence has been stopped and may be resumed. + + + + + + + process occurrence has come to a premature end and cannot be + resumed. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::PROCESS_STATE)}} + + + + + + + Controlled vocabulary for ValveState + + + + + + + {{block(ValveState)}} where flow is allowed and the aperture is + static. > Note: For a binary value, `OPEN` indicates the valve + has the maximum possible aperture. + + + + + + + valve is transitioning from a `CLOSED` state to an `OPEN` state. + + + + + + + {{block(ValveState)}} where flow is not possible, the aperture is + static, and the valve is completely shut. + + + + + + + valve is transitioning from an `OPEN` state to a `CLOSED` state. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::VALVE_STATE)}} + + + + + + + Controlled vocabulary for LockState + + + + + + + mechanism is engaged and preventing the associated + {{block(Component)}} from being opened or operated. + + + + + + + mechanism is disengaged and the associated {{block(Component)}} is + able to be opened or operated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::LOCK_STATE)}} + + + + + + + {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + + {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + + {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + Controlled vocabulary for OperatingMode + + + + + + + automatically execute instructions from a recipe or program. > + Note: Setpoint comes from a recipe. + + + + + + + execute instructions from an external agent or person. > Note 1 + to entry: Valve or switch is manipulated by an agent/person. > + Note 2 to entry: Direct control of the PID output. % of the range: A + user manually sets the % output, not the setpoint. + + + + + + + executes a single instruction from a recipe or program. > Note 1 + to entry: Setpoint is entered and fixed, but the PID is controlling. + > Note 2 to entry: Still goes through the PID control system. + > Note 3 to entry: Manual fixed entry from a recipe. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::OPERATING_MODE)}} + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + + {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + + {{def(EventEnum::FIXTURE_ID)}} + + + + + + + Controlled vocabulary for PartCountType + + + + + + + count is of individual items. + + + + + + + pre-specified group of items. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + + {{def(EventEnum::CLOCK_TIME)}} + + + + + + + {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + + {{def(EventEnum::NETWORK_PORT)}} + + + + + + + {{def(EventEnum::HOST_NAME)}} + + + + + + + + + + {{def(EventEnum::HOST_NAME)}} + + + + + + + Controlled vocabulary for LeakDetect + + + + + + + leak is currently being detected. + + + + + + + leak is currently not being detected. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + + + + + + {{def(EventEnum::LEAK_DETECT)}} + + + + + + + Controlled vocabulary for BatteryState + + + + + + + {{block(Component)}} is at it's maximum rated charge level. + + + + + + + {{block(Component)}}'s charge is increasing. + + + + + + + {{block(Component)}}'s charge is decreasing. + + + + + + + {{block(Component)}} is at it's minimum charge level. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::BATTERY_STATE)}} + + + + + + + {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + + {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + + {{def(EventEnum::SENSOR_STATE)}} + + + + + + + tabular {{def(EventEnum::COMPONENT_DATA)}} If the {{block(Component)}} + multiplicity can be determined, the device model **MUST** use a fixed + set of {{block(Component)}}s. {{block(ComponentData)}} **MUST** provide + a {{block(DataItem)}} {{block(Definition)}}. + + + + + + + + + + tabular {{def(EventEnum::COMPONENT_DATA)}} If the {{block(Component)}} + multiplicity can be determined, the device model **MUST** use a fixed + set of {{block(Component)}}s. {{block(ComponentData)}} **MUST** provide + a {{block(DataItem)}} {{block(Definition)}}. + + + + + + + tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + + tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + + tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + tabular representation of {{def(EventEnum::FEATURE_MEASUREMENT)}} + {{block(FeatureMeasurement)}} **MAY** include a {{term(characteristic)}} + in which case it **MAY** include a `CHARACTERISTIC_STATUS`. + + + + + + + + + + tabular representation of {{def(EventEnum::FEATURE_MEASUREMENT)}} + {{block(FeatureMeasurement)}} **MAY** include a {{term(characteristic)}} + in which case it **MAY** include a `CHARACTERISTIC_STATUS`. + + + + + + + {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, `RADIUS`, + `ANGLE`, `LENGTH`, etc. + + + + + + + + + + {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, `RADIUS`, + `ANGLE`, `LENGTH`, etc. + + + + + + + {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + + {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + + {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + Controlled vocabulary for CharacteristicStatus + + + + + + + measurement is within acceptable tolerances. + + + + + + + measurement is not within acceptable tolerances. + + + + + + + failed, but acceptable constraints achievable by utilizing + additional manufacturing processes. + + + + + + + measurement is indeterminate due to an equipment failure. + + + + + + + measurement cannot be determined. + + + + + + + measurement cannot be evaluated. + + + + + + + nominal provided without tolerance limits. {{cite(QIF 3:2018 + 5.10.2.6)}} + + + + + + + status of measurement cannot be determined. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + Controlled vocabulary for UncertaintyType + + + + + + + {{term(combined standard uncertainty)}}. + + + + + + + {{term(standard uncertainty)}} using arithmetic mean or average the + observations. {{cite(JCGM 100:2008 4.2)}} + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + + {{def(EventEnum::UNCERTAINTY)}} + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + + {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + + {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + + {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + + {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + {{def(EventEnum::THICKNESS)}} + + + + + + + + + + {{def(EventEnum::THICKNESS)}} + + + + + + + {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + + {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + + {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + + {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + + {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + + {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + + {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + Controlled vocabulary for InterfaceState + + + + + + + {{block(Interface)}} is currently operational and performing as + expected. + + + + + + + {{block(Interface)}} is currently not operational. + + + + + + + Value is indeterminate + + + + + + + + + {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + + + + + + {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + Discrete of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + Discrete of {{def(EventEnum::PART_COUNT)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_ID)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + Discrete of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::PALLET_ID)}} + + + + + + + Discrete of {{def(EventEnum::MESSAGE)}} + + + + + + + + + + Discrete of {{def(EventEnum::MESSAGE)}} + + + + + + + Discrete of {{def(EventEnum::BLOCK)}} + + + + + + + + + + Discrete of {{def(EventEnum::BLOCK)}} + + + + + + + Constraints for Entry Values + + + + + + the key + + + + + + + an indicatore that the entry has been removed + + + + + + + + Constraints for Entry Values + + + + + + + DataSet of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + DataSet of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + DataSet of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + DataSet of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + DataSet of {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::AVAILABILITY)}} + + + + + + + DataSet of {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::AVAILABILITY)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_STATE)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_STATE)}} + + + + + + + DataSet of {{def(EventEnum::BLOCK)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::BLOCK)}} + + + + + + + DataSet of {{def(EventEnum::BLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::BLOCK)}} + + + + + + + DataSet of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + DataSet of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + DataSet of {{def(EventEnum::CODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CODE)}} + + + + + + + DataSet of {{def(EventEnum::CODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CODE)}} + + + + + + + DataSet of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + DataSet of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + DataSet of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + DataSet of {{def(EventEnum::DATE_CODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DATE_CODE)}} + + + + + + + DataSet of {{def(EventEnum::DATE_CODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DATE_CODE)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + DataSet of {{def(EventEnum::DIRECTION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DIRECTION)}} + + + + + + + DataSet of {{def(EventEnum::DIRECTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DIRECTION)}} + + + + + + + DataSet of {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DOOR_STATE)}} + + + + + + + DataSet of {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DOOR_STATE)}} + + + + + + + DataSet of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + DataSet of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + DataSet of {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::END_OF_BAR)}} + + + + + + + DataSet of {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::END_OF_BAR)}} + + + + + + + DataSet of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + DataSet of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + DataSet of {{def(EventEnum::EXECUTION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::EXECUTION)}} + + + + + + + DataSet of {{def(EventEnum::EXECUTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::EXECUTION)}} + + + + + + + DataSet of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + DataSet of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + DataSet of {{def(EventEnum::HARDNESS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::HARDNESS)}} + + + + + + + DataSet of {{def(EventEnum::HARDNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::HARDNESS)}} + + + + + + + DataSet of {{def(EventEnum::LINE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LINE)}} + + + + + + + DataSet of {{def(EventEnum::LINE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LINE)}} + + + + + + + DataSet of {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LINE_LABEL)}} + + + + + + + DataSet of {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LINE_LABEL)}} + + + + + + + DataSet of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + DataSet of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + + + + + + + + DataSet of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + DataSet of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + DataSet of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + DataSet of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + DataSet of {{def(EventEnum::MESSAGE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MESSAGE)}} + + + + + + + DataSet of {{def(EventEnum::MESSAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MESSAGE)}} + + + + + + + DataSet of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + DataSet of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + DataSet of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PALLET_ID)}} + + + + + + + DataSet of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PALLET_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::PART_DETECT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_DETECT)}} + + + + + + + DataSet of {{def(EventEnum::PART_DETECT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_DETECT)}} + + + + + + + DataSet of {{def(EventEnum::PART_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::PATH_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PATH_MODE)}} + + + + + + + DataSet of {{def(EventEnum::PATH_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PATH_MODE)}} + + + + + + + DataSet of {{def(EventEnum::POWER_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::POWER_STATE)}} + + + + + + + DataSet of {{def(EventEnum::POWER_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::POWER_STATE)}} + + + + + + + DataSet of {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::POWER_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::POWER_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + DataSet of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + DataSet of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + DataSet of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + DataSet of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + DataSet of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + DataSet of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_ID)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_ID)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + DataSet of {{def(EventEnum::USER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::USER)}} + + + + + + + DataSet of {{def(EventEnum::USER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::USER)}} + + + + + + + DataSet of {{def(EventEnum::VARIABLE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::VARIABLE)}} + + + + + + + DataSet of {{def(EventEnum::VARIABLE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::VARIABLE)}} + + + + + + + DataSet of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + DataSet of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + DataSet of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + + + + + + + + DataSet of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + DataSet of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + DataSet of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + DataSet of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + DataSet of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + DataSet of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + DataSet of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + DataSet of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + DataSet of {{def(EventEnum::FIRMWARE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::FIRMWARE)}} + + + + + + + DataSet of {{def(EventEnum::FIRMWARE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::FIRMWARE)}} + + + + + + + DataSet of {{def(EventEnum::APPLICATION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::APPLICATION)}} + + + + + + + DataSet of {{def(EventEnum::APPLICATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::APPLICATION)}} + + + + + + + DataSet of {{def(EventEnum::LIBRARY)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LIBRARY)}} + + + + + + + DataSet of {{def(EventEnum::LIBRARY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LIBRARY)}} + + + + + + + DataSet of {{def(EventEnum::HARDWARE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::HARDWARE)}} + + + + + + + DataSet of {{def(EventEnum::HARDWARE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::HARDWARE)}} + + + + + + + DataSet of {{def(EventEnum::NETWORK)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::NETWORK)}} + + + + + + + DataSet of {{def(EventEnum::NETWORK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::NETWORK)}} + + + + + + + DataSet of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + + + + + + DataSet of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + DataSet of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + DataSet of translations along X, Y, and Z axes are expressed as x,y, and + z respectively within a 3-dimensional vector. + + + + + + + + + + + + + + DataSet of translations along X, Y, and Z axes are expressed as x,y, and + z respectively within a 3-dimensional vector. + + + + + + + DataSet of translations along X, Y, and Z axes are expressed as x,y, and + z respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of translations along X, Y, and Z axes are expressed as x,y, and + z respectively within a 3-dimensional vector. + + + + + + + DataSet of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + DataSet of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + DataSet of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + DataSet of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + DataSet of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + DataSet of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + DataSet of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + DataSet of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + DataSet of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + DataSet of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + DataSet of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + DataSet of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + DataSet of {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::VALVE_STATE)}} + + + + + + + DataSet of {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::VALVE_STATE)}} + + + + + + + DataSet of {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LOCK_STATE)}} + + + + + + + DataSet of {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LOCK_STATE)}} + + + + + + + DataSet of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + DataSet of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + DataSet of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + DataSet of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + DataSet of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + DataSet of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + DataSet of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + DataSet of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + DataSet of {{def(EventEnum::HOST_NAME)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::HOST_NAME)}} + + + + + + + DataSet of {{def(EventEnum::HOST_NAME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::HOST_NAME)}} + + + + + + + DataSet of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + DataSet of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + DataSet of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + DataSet of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + DataSet of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + DataSet of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + DataSet of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + DataSet of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + DataSet of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + + + + + + + + DataSet of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + DataSet of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + DataSet of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + + + + + + DataSet of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + DataSet of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + DataSet of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + + + + + + DataSet of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + DataSet of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + DataSet of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + + + + + + + + DataSet of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + DataSet of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + DataSet of See {{sect(AlarmLimits)}}. + + + + + + + + + + + + + + DataSet of See {{sect(AlarmLimits)}}. + + + + + + + DataSet of See {{sect(AlarmLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of See {{sect(AlarmLimits)}}. + + + + + + + DataSet of See {{sect(ControlLimits)}}. + + + + + + + + + + + + + + DataSet of See {{sect(ControlLimits)}}. + + + + + + + DataSet of See {{sect(ControlLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of See {{sect(ControlLimits)}}. + + + + + + + DataSet of See {{sect(SpecificationLimits)}}. + + + + + + + + + + + + + + DataSet of See {{sect(SpecificationLimits)}}. + + + + + + + DataSet of See {{sect(SpecificationLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of See {{sect(SpecificationLimits)}}. + + + + + + + DataSet of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + DataSet of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + DataSet of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + DataSet of {{def(EventEnum::THICKNESS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::THICKNESS)}} + + + + + + + DataSet of {{def(EventEnum::THICKNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::THICKNESS)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + DataSet of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + DataSet of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + DataSet of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE)}} + + + + + + + DataSet of {{def(SampleEnum::ANGLE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ANGLE)}} + + + + + + + DataSet of {{def(SampleEnum::ANGLE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ANGLE)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + DataSet of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + DataSet of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + DataSet of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + DataSet of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + DataSet of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + DataSet of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + DataSet of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + DataSet of {{def(SampleEnum::DENSITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DENSITY)}} + + + + + + + DataSet of {{def(SampleEnum::DENSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DENSITY)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + DataSet of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + DataSet of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + DataSet of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + DataSet of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + DataSet of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::FLOW)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FLOW)}} + + + + + + + DataSet of {{def(SampleEnum::FLOW)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FLOW)}} + + + + + + + DataSet of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FREQUENCY)}} + + + + + + + DataSet of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FREQUENCY)}} + + + + + + + DataSet of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + DataSet of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + DataSet of {{def(SampleEnum::LENGTH)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::LENGTH)}} + + + + + + + DataSet of {{def(SampleEnum::LENGTH)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::LENGTH)}} + + + + + + + DataSet of {{def(SampleEnum::LEVEL)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + DataSet of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + DataSet of {{def(SampleEnum::LOAD)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::LOAD)}} + + + + + + + DataSet of {{def(SampleEnum::LOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::LOAD)}} + + + + + + + DataSet of {{def(SampleEnum::MASS)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::MASS)}} + + + + + + + DataSet of {{def(SampleEnum::MASS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::MASS)}} + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + DataSet of Example + + + + + + + + + + + + + + DataSet of Example + + + + + + + DataSet of Example + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of Example + + + + + + + DataSet of {{def(SampleEnum::PH)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::PH)}} + + + + + + + DataSet of {{def(SampleEnum::PH)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::PH)}} + + + + + + + DataSet of {{def(SampleEnum::POSITION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::POSITION)}} + + + + + + + DataSet of {{def(SampleEnum::POSITION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::POSITION)}} + + + + + + + DataSet of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + DataSet of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + DataSet of Description + + + + + + + + + + + + + + DataSet of Description + + + + + + + DataSet of Description + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of Description + + + + + + + DataSet of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + DataSet of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + DataSet of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::RESISTANCE)}} + + + + + + + DataSet of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::RESISTANCE)}} + + + + + + + DataSet of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + DataSet of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + DataSet of {{def(SampleEnum::STRAIN)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::STRAIN)}} + + + + + + + DataSet of {{def(SampleEnum::STRAIN)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::STRAIN)}} + + + + + + + DataSet of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + DataSet of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + DataSet of {{def(SampleEnum::TENSION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::TENSION)}} + + + + + + + DataSet of {{def(SampleEnum::TENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::TENSION)}} + + + + + + + DataSet of {{def(SampleEnum::TILT)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::TILT)}} + + + + + + + DataSet of {{def(SampleEnum::TILT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::TILT)}} + + + + + + + DataSet of {{def(SampleEnum::TORQUE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::TORQUE)}} + + + + + + + DataSet of {{def(SampleEnum::TORQUE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::TORQUE)}} + + + + + + + DataSet of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VISCOSITY)}} + + + + + + + DataSet of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VISCOSITY)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + DataSet of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + DataSet of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + DataSet of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + DataSet of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::WATTAGE)}} + + + + + + + DataSet of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::WATTAGE)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + DataSet of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DIAMETER)}} + + + + + + + DataSet of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DIAMETER)}} + + + + + + + DataSet of {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ORIENTATION)}} + + + + + + + DataSet of {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ORIENTATION)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + DataSet of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DECELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DECELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + DataSet of The force per unit area measured relative to a vacuum. + + + + + + + + + + + + + + DataSet of The force per unit area measured relative to a vacuum. + + + + + + + DataSet of The force per unit area measured relative to a vacuum. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of The force per unit area measured relative to a vacuum. + + + + + + + DataSet of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::OPENNESS)}} + + + + + + + DataSet of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::OPENNESS)}} + + + + + + + DataSet of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEW_POINT)}} + + + + + + + DataSet of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEW_POINT)}} + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + DataSet of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + DataSet of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + DataSet of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + A cell of a table + + + + + + the key + + + + + + + + A cell of a table + + + + + + + {{term(key-value pair)}} published as part of a {{block(Table)}}. > + Note: In the {{term(XML)}} representation, {{block(TableEntry)}} + **MUST** appear as {{block(Entry)}}. + + + + + + + + + + + + + + {{term(key-value pair)}} published as part of a {{block(Table)}}. > + Note: In the {{term(XML)}} representation, {{block(TableEntry)}} + **MUST** appear as {{block(Entry)}}. + + + + + + + Table Entry of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + Cell of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + Table of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + Table Entry of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + Cell of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + Table of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + Cell of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + Table of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + Table Entry of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + Cell of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + Table of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + Table Entry of {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::AVAILABILITY)}} + + + + + + + Cell of {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::AVAILABILITY)}} + + + + + + + Table of {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::AVAILABILITY)}} + + + + + + + Table Entry of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + Cell of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + Table of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + Table Entry of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + Cell of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + Table of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + Table Entry of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + Cell of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + Table of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + Table Entry of {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::AXIS_STATE)}} + + + + + + + Cell of {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::AXIS_STATE)}} + + + + + + + Table of {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::AXIS_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::BLOCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::BLOCK)}} + + + + + + + Cell of {{def(EventEnum::BLOCK)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::BLOCK)}} + + + + + + + Table of {{def(EventEnum::BLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::BLOCK)}} + + + + + + + Table Entry of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + Cell of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + Table of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + Cell of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + Table of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + Table Entry of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + Cell of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + Table of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::CODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CODE)}} + + + + + + + Cell of {{def(EventEnum::CODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CODE)}} + + + + + + + Table of {{def(EventEnum::CODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CODE)}} + + + + + + + Table Entry of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + Cell of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + Table of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + Cell of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + Table of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + Cell of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + Table of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + Table Entry of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + Cell of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + Table of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + Table Entry of {{def(EventEnum::DATE_CODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DATE_CODE)}} + + + + + + + Cell of {{def(EventEnum::DATE_CODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DATE_CODE)}} + + + + + + + Table of {{def(EventEnum::DATE_CODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DATE_CODE)}} + + + + + + + Table Entry of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + Cell of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + Table of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + Table Entry of {{def(EventEnum::DIRECTION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DIRECTION)}} + + + + + + + Cell of {{def(EventEnum::DIRECTION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DIRECTION)}} + + + + + + + Table of {{def(EventEnum::DIRECTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DIRECTION)}} + + + + + + + Table Entry of {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DOOR_STATE)}} + + + + + + + Cell of {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DOOR_STATE)}} + + + + + + + Table of {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DOOR_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + Cell of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + Table of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + Table Entry of {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::END_OF_BAR)}} + + + + + + + Cell of {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::END_OF_BAR)}} + + + + + + + Table of {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::END_OF_BAR)}} + + + + + + + Table Entry of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + Cell of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + Table of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::EXECUTION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::EXECUTION)}} + + + + + + + Cell of {{def(EventEnum::EXECUTION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::EXECUTION)}} + + + + + + + Table of {{def(EventEnum::EXECUTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::EXECUTION)}} + + + + + + + Table Entry of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + Cell of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + Table of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::HARDNESS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::HARDNESS)}} + + + + + + + Cell of {{def(EventEnum::HARDNESS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::HARDNESS)}} + + + + + + + Table of {{def(EventEnum::HARDNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::HARDNESS)}} + + + + + + + Table Entry of {{def(EventEnum::LINE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LINE)}} + + + + + + + Cell of {{def(EventEnum::LINE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LINE)}} + + + + + + + Table of {{def(EventEnum::LINE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LINE)}} + + + + + + + Table Entry of {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LINE_LABEL)}} + + + + + + + Cell of {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LINE_LABEL)}} + + + + + + + Table of {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LINE_LABEL)}} + + + + + + + Table Entry of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + Cell of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + Table of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + Table Entry of {{block(Resource)}} composed of material that is consumed + or used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{block(Resource)}} composed of material that is consumed + or used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + Cell of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + + + + + + + + Cell of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + Table of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + Table Entry of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + Cell of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + Table of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + Table Entry of {{def(EventEnum::MESSAGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MESSAGE)}} + + + + + + + Cell of {{def(EventEnum::MESSAGE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::MESSAGE)}} + + + + + + + Table of {{def(EventEnum::MESSAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MESSAGE)}} + + + + + + + Table Entry of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + Cell of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + Table of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PALLET_ID)}} + + + + + + + Cell of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PALLET_ID)}} + + + + + + + Table of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PALLET_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_COUNT)}} + + + + + + + Cell of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_COUNT)}} + + + + + + + Table of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::PART_DETECT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_DETECT)}} + + + + + + + Cell of {{def(EventEnum::PART_DETECT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_DETECT)}} + + + + + + + Table of {{def(EventEnum::PART_DETECT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_DETECT)}} + + + + + + + Table Entry of {{def(EventEnum::PART_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_ID)}} + + + + + + + Cell of {{def(EventEnum::PART_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_ID)}} + + + + + + + Table of {{def(EventEnum::PART_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_NUMBER)}} + + + + + + + Cell of {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_NUMBER)}} + + + + + + + Table of {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_NUMBER)}} + + + + + + + Table Entry of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + Cell of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + Table of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + Table Entry of {{def(EventEnum::PATH_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PATH_MODE)}} + + + + + + + Cell of {{def(EventEnum::PATH_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PATH_MODE)}} + + + + + + + Table of {{def(EventEnum::PATH_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PATH_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::POWER_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::POWER_STATE)}} + + + + + + + Cell of {{def(EventEnum::POWER_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::POWER_STATE)}} + + + + + + + Table of {{def(EventEnum::POWER_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::POWER_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::POWER_STATUS)}} + + + + + + + Cell of {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::POWER_STATUS)}} + + + + + + + Table of {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::POWER_STATUS)}} + + + + + + + Table Entry of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + Cell of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + Table of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM)}} + + + + + + + Table of {{def(EventEnum::PROGRAM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial + value is not defined, the nesting level associated with the highest or + initial nesting level of the program **MUST** default to zero (0). + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial + value is not defined, the nesting level associated with the highest or + initial nesting level of the program **MUST** default to zero (0). + + + + + + + Cell of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + Table of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + Table Entry of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + Cell of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + Table of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + Cell of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + + + + + + Cell of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + Table of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + Table Entry of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + Cell of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + Table of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + Table Entry of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + Cell of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + Table of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + Table Entry of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + Cell of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + Table of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + Table Entry of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + Cell of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + Table of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + Table Entry of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_ID)}} + + + + + + + Cell of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_ID)}} + + + + + + + Table of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_ID)}} + + + + + + + Table Entry of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + Cell of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + Table of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + Table Entry of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + Cell of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + Table of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + Table Entry of {{def(EventEnum::USER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::USER)}} + + + + + + + Cell of {{def(EventEnum::USER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::USER)}} + + + + + + + Table of {{def(EventEnum::USER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::USER)}} + + + + + + + Table Entry of {{def(EventEnum::VARIABLE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::VARIABLE)}} + + + + + + + Cell of {{def(EventEnum::VARIABLE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::VARIABLE)}} + + + + + + + Table of {{def(EventEnum::VARIABLE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::VARIABLE)}} + + + + + + + Table Entry of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + Cell of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + + + + + + + + Cell of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + Table of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + Table Entry of leaf {{block(Component)}} composed of a string like piece + or filament of relatively rigid or flexible material provided in a + variety of diameters. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of leaf {{block(Component)}} composed of a string like piece + or filament of relatively rigid or flexible material provided in a + variety of diameters. + + + + + + + Cell of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + + + + + + + + Cell of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + Table of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + Table Entry of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + Cell of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + Table of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + Table Entry of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + Cell of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + Table of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + Table Entry of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + Cell of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + Table of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + Table Entry of {{def(EventEnum::FIRMWARE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::FIRMWARE)}} + + + + + + + Cell of {{def(EventEnum::FIRMWARE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::FIRMWARE)}} + + + + + + + Table of {{def(EventEnum::FIRMWARE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::FIRMWARE)}} + + + + + + + Table Entry of {{def(EventEnum::APPLICATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::APPLICATION)}} + + + + + + + Cell of {{def(EventEnum::APPLICATION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::APPLICATION)}} + + + + + + + Table of {{def(EventEnum::APPLICATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::APPLICATION)}} + + + + + + + Table Entry of {{def(EventEnum::LIBRARY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LIBRARY)}} + + + + + + + Cell of {{def(EventEnum::LIBRARY)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LIBRARY)}} + + + + + + + Table of {{def(EventEnum::LIBRARY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LIBRARY)}} + + + + + + + Table Entry of {{def(EventEnum::HARDWARE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::HARDWARE)}} + + + + + + + Cell of {{def(EventEnum::HARDWARE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::HARDWARE)}} + + + + + + + Table of {{def(EventEnum::HARDWARE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::HARDWARE)}} + + + + + + + Table Entry of {{def(EventEnum::NETWORK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::NETWORK)}} + + + + + + + Cell of {{def(EventEnum::NETWORK)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::NETWORK)}} + + + + + + + Table of {{def(EventEnum::NETWORK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::NETWORK)}} + + + + + + + Table Entry of rotations about X, Y, and Z axes are expressed in A, B, + and C respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of rotations about X, Y, and Z axes are expressed in A, B, + and C respectively within a 3-dimensional vector. + + + + + + + Cell of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + + + + + + Cell of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + Table of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + Table Entry of translations along X, Y, and Z axes are expressed as x,y, + and z respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of translations along X, Y, and Z axes are expressed as x,y, + and z respectively within a 3-dimensional vector. + + + + + + + Cell of translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + + + + + + + + Cell of translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + Table of translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + Table Entry of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + Cell of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + Table of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + Cell of {{def(EventEnum::PART_STATUS)}} If unique identifier is given, + part status is for that individual. If group identifier is given without + a unique identifier, then the status is assumed to be for the whole + group. + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_STATUS)}} If unique identifier is given, + part status is for that individual. If group identifier is given without + a unique identifier, then the status is assumed to be for the whole + group. + + + + + + + Table of {{def(EventEnum::PART_STATUS)}} If unique identifier is given, + part status is for that individual. If group identifier is given without + a unique identifier, then the status is assumed to be for the whole + group. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_STATUS)}} If unique identifier is given, + part status is for that individual. If group identifier is given without + a unique identifier, then the status is assumed to be for the whole + group. + + + + + + + Table Entry of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + Cell of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + Table of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + Table Entry of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + Cell of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + Table of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Cell of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table Entry of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + Cell of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + Table of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + Table Entry of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + Cell of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + Table of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + Table Entry of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + Cell of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + Table of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + Table Entry of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + Cell of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + Table of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + Table Entry of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + Cell of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + Table of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + Table Entry of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + Cell of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + Table of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + Table Entry of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + Cell of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + Table of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + Table Entry of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + Cell of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + Table of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + Table Entry of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + Cell of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + Table of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + Table Entry of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + Cell of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + Table of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + Table Entry of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + Cell of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + Table of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Cell of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table Entry of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Cell of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table Entry of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + Cell of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + Table of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + Cell of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + Table of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + Cell of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + Table of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + Cell of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + Table of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + Cell of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + Table of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + Cell of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + Table of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::VALVE_STATE)}} + + + + + + + Cell of {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::VALVE_STATE)}} + + + + + + + Table of {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::VALVE_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LOCK_STATE)}} + + + + + + + Cell of {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LOCK_STATE)}} + + + + + + + Table of {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LOCK_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + Cell of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + Table of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + Cell of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + Table of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + Cell of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + Table of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + Cell of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + Table of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + Cell of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + + + + + + Cell of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + Table of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + Table Entry of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + Cell of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + Table of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + Cell of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + Table of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + Table Entry of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + Cell of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + Table of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + Table Entry of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + Cell of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + Table of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + Table Entry of {{def(EventEnum::HOST_NAME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::HOST_NAME)}} + + + + + + + Cell of {{def(EventEnum::HOST_NAME)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::HOST_NAME)}} + + + + + + + Table of {{def(EventEnum::HOST_NAME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::HOST_NAME)}} + + + + + + + Table Entry of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + Cell of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + Table of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + Table Entry of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + Cell of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + Table of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + Cell of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + Table of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + Table Entry of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + Cell of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + Table of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + Table Entry of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + Cell of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + + + + + + + + Cell of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + Table of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + Cell of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + + + + + + Cell of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + Table of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + Cell of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + + + + + + Cell of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + Table of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + Cell of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + + + + + + + + Cell of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + Table of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + Table Entry of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + Cell of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + Table of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + Table of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + Table of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + Table of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + Table Entry of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + Cell of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + Table of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + Table Entry of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + Cell of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + Table of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + Table Entry of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + Cell of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + Table of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + Table Entry of See {{sect(AlarmLimits)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of See {{sect(AlarmLimits)}}. + + + + + + + Cell of See {{sect(AlarmLimits)}}. + + + + + + + + + + + + + + Cell of See {{sect(AlarmLimits)}}. + + + + + + + Table of See {{sect(AlarmLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of See {{sect(AlarmLimits)}}. + + + + + + + Table Entry of See {{sect(ControlLimits)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of See {{sect(ControlLimits)}}. + + + + + + + Cell of See {{sect(ControlLimits)}}. + + + + + + + + + + + + + + Cell of See {{sect(ControlLimits)}}. + + + + + + + Table of See {{sect(ControlLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of See {{sect(ControlLimits)}}. + + + + + + + Table Entry of See {{sect(SpecificationLimits)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of See {{sect(SpecificationLimits)}}. + + + + + + + Cell of See {{sect(SpecificationLimits)}}. + + + + + + + + + + + + + + Cell of See {{sect(SpecificationLimits)}}. + + + + + + + Table of See {{sect(SpecificationLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of See {{sect(SpecificationLimits)}}. + + + + + + + Table Entry of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + Cell of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + Table of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + Table Entry of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + Cell of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + Table of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + Table Entry of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + Cell of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + Table of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + Table Entry of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + Cell of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + Table of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + Table Entry of {{def(EventEnum::THICKNESS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::THICKNESS)}} + + + + + + + Cell of {{def(EventEnum::THICKNESS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::THICKNESS)}} + + + + + + + Table of {{def(EventEnum::THICKNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::THICKNESS)}} + + + + + + + Table Entry of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + Cell of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + Table of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + Cell of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + Table of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + Cell of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + Table of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + Cell of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + Table of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + Cell of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + Table of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + Cell of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + Table of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + Cell of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + Table of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + Table Entry of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ACCELERATION)}} + + + + + + + Cell of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ACCELERATION)}} + + + + + + + Table of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ACCELERATION)}} + + + + + + + Table Entry of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + Cell of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + Table of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE)}} + + + + + + + Cell of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::AMPERAGE)}} + + + + + + + Table of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::AMPERAGE)}} + + + + + + + Table Entry of {{def(SampleEnum::ANGLE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ANGLE)}} + + + + + + + Cell of {{def(SampleEnum::ANGLE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ANGLE)}} + + + + + + + Table of {{def(SampleEnum::ANGLE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ANGLE)}} + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + Cell of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + Table of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + Cell of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + Table of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + Table Entry of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + Cell of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + Table of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + Table Entry of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + Cell of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + Table of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + Table Entry of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + Cell of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + Table of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + Table Entry of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + Cell of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + Table of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + Table Entry of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + Cell of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + Table of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + Table Entry of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + Cell of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + Table of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + Table Entry of {{def(SampleEnum::DENSITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DENSITY)}} + + + + + + + Cell of {{def(SampleEnum::DENSITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DENSITY)}} + + + + + + + Table of {{def(SampleEnum::DENSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DENSITY)}} + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + Table of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + Table of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + Table of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + Table of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + Table of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + Table Entry of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + Cell of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + Table of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + Table Entry of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + Cell of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + Table of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + Table Entry of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + Cell of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + Table of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + Table Entry of {{def(SampleEnum::FLOW)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FLOW)}} + + + + + + + Cell of {{def(SampleEnum::FLOW)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FLOW)}} + + + + + + + Table of {{def(SampleEnum::FLOW)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FLOW)}} + + + + + + + Table Entry of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FREQUENCY)}} + + + + + + + Cell of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FREQUENCY)}} + + + + + + + Table of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FREQUENCY)}} + + + + + + + Table Entry of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + Cell of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + Table of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + Table Entry of {{def(SampleEnum::LENGTH)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::LENGTH)}} + + + + + + + Cell of {{def(SampleEnum::LENGTH)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::LENGTH)}} + + + + + + + Table of {{def(SampleEnum::LENGTH)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::LENGTH)}} + + + + + + + Table Entry of {{def(SampleEnum::LEVEL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::LEVEL)}} + + + + + + + Cell of {{def(SampleEnum::LEVEL)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::LEVEL)}} + + + + + + + Table of {{def(SampleEnum::LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::LEVEL)}} + + + + + + + Table Entry of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + Cell of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + Table of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + Table Entry of {{def(SampleEnum::LOAD)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::LOAD)}} + + + + + + + Cell of {{def(SampleEnum::LOAD)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::LOAD)}} + + + + + + + Table of {{def(SampleEnum::LOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::LOAD)}} + + + + + + + Table Entry of {{def(SampleEnum::MASS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::MASS)}} + + + + + + + Cell of {{def(SampleEnum::MASS)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::MASS)}} + + + + + + + Table of {{def(SampleEnum::MASS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::MASS)}} + + + + + + + Table Entry of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + Cell of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + Table of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + Table Entry of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Cell of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Table of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Table Entry of Example + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of Example + + + + + + + Cell of Example + + + + + + + + + + + + + + Cell of Example + + + + + + + Table of Example + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of Example + + + + + + + Table Entry of {{def(SampleEnum::PH)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::PH)}} + + + + + + + Cell of {{def(SampleEnum::PH)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::PH)}} + + + + + + + Table of {{def(SampleEnum::PH)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::PH)}} + + + + + + + Table Entry of {{def(SampleEnum::POSITION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::POSITION)}} + + + + + + + Cell of {{def(SampleEnum::POSITION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::POSITION)}} + + + + + + + Table of {{def(SampleEnum::POSITION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::POSITION)}} + + + + + + + Table Entry of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Cell of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Table of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Table Entry of Description + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of Description + + + + + + + Cell of Description + + + + + + + + + + + + + + Cell of Description + + + + + + + Table of Description + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of Description + + + + + + + Table Entry of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + Cell of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + Table of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + Table Entry of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::RESISTANCE)}} + + + + + + + Cell of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::RESISTANCE)}} + + + + + + + Table of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::RESISTANCE)}} + + + + + + + Table Entry of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + Cell of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + Table of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + Table Entry of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + Cell of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + Table of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + Table Entry of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + Cell of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + Table of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + Table Entry of {{def(SampleEnum::STRAIN)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::STRAIN)}} + + + + + + + Cell of {{def(SampleEnum::STRAIN)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::STRAIN)}} + + + + + + + Table of {{def(SampleEnum::STRAIN)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::STRAIN)}} + + + + + + + Table Entry of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + Cell of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + Table of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + Table Entry of {{def(SampleEnum::TENSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::TENSION)}} + + + + + + + Cell of {{def(SampleEnum::TENSION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::TENSION)}} + + + + + + + Table of {{def(SampleEnum::TENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::TENSION)}} + + + + + + + Table Entry of {{def(SampleEnum::TILT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::TILT)}} + + + + + + + Cell of {{def(SampleEnum::TILT)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::TILT)}} + + + + + + + Table of {{def(SampleEnum::TILT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::TILT)}} + + + + + + + Table Entry of {{def(SampleEnum::TORQUE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::TORQUE)}} + + + + + + + Cell of {{def(SampleEnum::TORQUE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::TORQUE)}} + + + + + + + Table of {{def(SampleEnum::TORQUE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::TORQUE)}} + + + + + + + Table Entry of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VELOCITY)}} + + + + + + + Cell of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VELOCITY)}} + + + + + + + Table of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VELOCITY)}} + + + + + + + Table Entry of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VISCOSITY)}} + + + + + + + Cell of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VISCOSITY)}} + + + + + + + Table of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VISCOSITY)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE)}} + + + + + + + Cell of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLTAGE)}} + + + + + + + Table of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLTAGE)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + Cell of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + Table of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + Cell of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + Table of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + Cell of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + Table of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + Cell of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + Table of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + Table Entry of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::WATTAGE)}} + + + + + + + Cell of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::WATTAGE)}} + + + + + + + Table of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::WATTAGE)}} + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + Cell of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + Table of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + Cell of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + Table of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + Cell of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + Table of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + Cell of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + Table of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + Table Entry of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + Cell of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + Table of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + Table Entry of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + Cell of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + Table of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + Table Entry of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + Cell of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + Table of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + Table Entry of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DIAMETER)}} + + + + + + + Cell of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DIAMETER)}} + + + + + + + Table of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DIAMETER)}} + + + + + + + Table Entry of {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ORIENTATION)}} + + + + + + + Cell of {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ORIENTATION)}} + + + + + + + Table of {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ORIENTATION)}} + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + Table of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + Table of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + Table of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + Table Entry of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + Cell of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + Table of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + Table Entry of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DECELERATION)}} + + + + + + + Cell of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DECELERATION)}} + + + + + + + Table of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DECELERATION)}} + + + + + + + Table Entry of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + Cell of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + Table of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + Cell of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + Table of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + Table Entry of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + Cell of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + Table of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + Table Entry of The force per unit area measured relative to a vacuum. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of The force per unit area measured relative to a vacuum. + + + + + + + Cell of The force per unit area measured relative to a vacuum. + + + + + + + + + + + + + + Cell of The force per unit area measured relative to a vacuum. + + + + + + + Table of The force per unit area measured relative to a vacuum. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of The force per unit area measured relative to a vacuum. + + + + + + + Table Entry of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::OPENNESS)}} + + + + + + + Cell of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::OPENNESS)}} + + + + + + + Table of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::OPENNESS)}} + + + + + + + Table Entry of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEW_POINT)}} + + + + + + + Cell of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEW_POINT)}} + + + + + + + Table of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEW_POINT)}} + + + + + + + Table Entry of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + Cell of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + + + + + + + + Cell of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + Table of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + Table Entry of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + Cell of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + Table of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + Table Entry of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + Cell of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + Table of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + Table Entry of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + Cell of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + Table of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + Table Entry of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + Cell of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + Table of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + Table Entry of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + Cell of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + Table of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Table Entry of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + Cell of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + Table of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + The description of the Condition + + + + + + + + The device's severity + + + + + + + + Identifier of an individual condition activation provided by a piece of + equipment + + + + + + + + A qualifier for the condition + + + + + + + The value is too high + + + + + + + The value is too low + + + + + + + + + Description + + + + + + + + + type of the power source. + + + + + + + The component specific Notifcation code + + + + + + + The component specific Notifcation code + + + + + + + An optional attribute that helps qualify the condition + + + + + + + The statistical operation on this data + + + + + + + + + + Description + + + + + + + Condition that has transitioned from Normal to either Warning or Fault + + + + + + + + Identifier of an individual condition activation provided by a + piece of equipment + + + + + + + + + + Condition that has transitioned from Normal to either Warning or Fault + + + + + + + The conditon can not be determined. + + + + + + + + + + The conditon can not be determined. + + + + + + + {{term(condition state)}} that indicates operation within specified + limits. + + + + + + + + + + {{term(condition state)}} that indicates operation within specified + limits. + + + + + + + {{term(condition state)}} that requires concern and supervision and may + become hazardous if no action is taken. + + + + + + + + + + {{term(condition state)}} that requires concern and supervision and may + become hazardous if no action is taken. + + + + + + + {{term(condition state)}} that requires intervention to continue + operation to function properly. + + + + + + + + + + {{term(condition state)}} that requires intervention to continue + operation to function properly. + + + + + + + DEPRECATED: An Notifcation code as defined by the component + + + + + + + + DEPRECATED: Types of Notifcations + + + + + + + A failure + + + + + + + A fault occurred + + + + + + + A spindle crash + + + + + + + A component has jammed + + + + + + + The component has been overloaded + + + + + + + E-Stop was pushed + + + + + + + A material failure has occurred + + + + + + + An operators message. Used with INFO severity + + + + + + + Another Notifcation type + + + + + + + + + DEPRECATED: The active or cleared state of the notification + + + + + + + The notification is active + + + + + + + The notification has been cleared + + + + + + + + + level of severity on a scale of 1-10. + + + + + + + The notification is critical + + + + + + + An error has occurred + + + + + + + A medium level notification that should be observed + + + + + + + This notification is for information purposes only + + + + + + + + + {{def(EventEnum::ALARM)}} + + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + level of severity on a scale of 1-10. + + + + + + + The state + + + + + + + The component specific Notifcation code + + + + + + + + + + {{def(EventEnum::ALARM)}} + + + + + + + The possible values for an interface event + + + + + + + The value is unavailable + + + + + + + The interface is not ready + + + + + + + The interface is ready + + + + + + + The interface is actively executing + + + + + + + The interface has completed the action + + + + + + + The interface action has failed + + + + + + + + + An abstract interface event + + + + + + + + + + + + + + An abstract interface event + + + + + + + The state of the interface + + + + + + + The value is unavailable + + + + + + + The interface is enabled + + + + + + + The interface is disabled + + + + + + \ No newline at end of file diff --git a/schemas/MTConnectStreams_2.5_1.0.xsd b/schemas/MTConnectStreams_2.5_1.0.xsd new file mode 100644 index 000000000..ceb4b0d21 --- /dev/null +++ b/schemas/MTConnectStreams_2.5_1.0.xsd @@ -0,0 +1,46228 @@ + + + + + + + root entity of an {{term(MTConnectStreams Response Document)}} that + contains the {{term(Observation Information Model)}} of one or more + {{block(Device)}} entities. + ![MTConnectStreams](figures/MTConnectStreams.png + "MTConnectStreams"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectStreams)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + The sender of the message + + + + + + + + The date and time the document was created + + + + + + + + A sequence number + + + + + + + + + + + A debugging flag for testing. + + + + + + + + The instance number of the agent, used for fault tolerance + + + + + + + + + + + The size of the agents buffer + + + + + + + + + + + The time the sample was reported + + + + + + + + The time a sample occurred + + + + + + + + A version number + + + + + + + + A short name for any element + + + + + + + + A universally unique id that uniquely identifies the element for + it's entire life + + + + + + + + A serial number for a piece of equipment + + + + + + + + The measurement source + + + + + + + + A sample rate in milliseconds per sample + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + + An identifier + + + + + + + + The number significant digits + + + + + + + + The item's reference to the Device model composition + + + + + + + + A length of time in seconds + + + + + + + + A flag indicating the item has been removed + + + + + + + + The key for adata set + + + + + + + + A timestamp in 8601 format of the last update of the Device information + for any device + + + + + + + + The unique id of the asset + + + + + + + + An asset type + + + + + + + + The maximum number of assets + + + + + + + + + + + The number of assets + + + + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + The limit of a value + + + + + + + + Common floating point sample value + + + + + + + + + + + + A three dimensional value 'X Y Z' or 'A B C' + + + + + + + + + + + A description + + + + + + + + Extended tyoe for The types of measurements available + + + + + + + + + + The types of measurements available + + + + + + + positive rate of change of velocity. + + + + + + + accumulated time for an activity or event. + + + + + + + strength of electrical current. **DEPRECATED** in *Version 1.6*. + Replaced by `AMPERAGE_AC` and `AMPERAGE_DC`. + + + + + + + angular position. + + + + + + + positive rate of change of angular velocity. + + + + + + + rate of change of angular position. + + + + + + + feedrate of a linear axis. + + + + + + + fluid capacity of an object or container. + + + + + + + geometric capacity of an object or container. + + + + + + + percentage of one component within a mixture of components. + + + + + + + ability of a material to conduct electricity. + + + + + + + speed difference (relative velocity) between the cutting mechanism + and the surface of the workpiece it is operating on. + + + + + + + volumetric mass of a material per unit volume of that material. + + + + + + + rate of change in spatial volume of material deposited in an + additive manufacturing process. + + + + + + + density of the material deposited in an additive manufacturing + process per unit of volume. + + + + + + + mass of the material deposited in an additive manufacturing process. + + + + + + + rate at which a spatial volume of material is deposited in an + additive manufacturing process. + + + + + + + spatial volume of material to be deposited in an additive + manufacturing process. + + + + + + + change in position of an object. + + + + + + + {{block(Wattage)}} used or generated by a component over an interval + of time. + + + + + + + amount of time a piece of equipment or a sub-part of a piece of + equipment has performed specific activities. + + + + + + + amount of a substance remaining compared to the planned maximum + amount of that substance. + + + + + + + rate of flow of a fluid. + + + + + + + number of occurrences of a repeating event per unit time. + + + + + + + position in three-dimensional space. **DEPRECATED** in Version 1.1. + + + + + + + length of an object. + + + + + + + level of a resource. **DEPRECATED** in *Version 1.2*. See + `FILL_LEVEL`. + + + + + + + {{term(force)}} applied to a mass in one direction only. + + + + + + + actual versus the standard rating of a piece of equipment. + + + + + + + mass of an object(s) or an amount of material. + + + + + + + feedrate for the axes, or a single axis, associated with a + {{block(Path)}} component. + + + + + + + feedrate for the axes, or a single axis. + + + + + + + position of a control point associated with a {{block(Controller)}} + or a {{block(Path)}}. + + + + + + + acidity or alkalinity of a solution. + + + + + + + point along an axis in a {{term(cartesian coordinate system)}}. + + + + + + + ratio of real power flowing to a load to the apparent power in that + AC circuit. + + + + + + + force per unit area measured relative to atmospheric pressure. + Commonly referred to as gauge pressure. + + + + + + + amount of time a piece of equipment has performed different types of + activities associated with the process being performed at that piece + of equipment. + + + + + + + degree to which a substance opposes the passage of an electric + current. + + + + + + + rotational speed of a rotary axis. + + + + + + + sound level or sound pressure level relative to atmospheric + pressure. + + + + + + + rotational speed of the rotary axis. **DEPRECATED** in *Version + 1.2*. Replaced by `ROTARY_VELOCITY`. + + + + + + + amount of deformation per unit length of an object when a load is + applied. + + + + + + + degree of hotness or coldness measured on a definite scale. + + + + + + + force that stretches or elongates an object. + + + + + + + angular displacement. + + + + + + + turning force exerted on an object or by an object. + + + + + + + rate of change of position of a {{block(Component)}}. + + + + + + + fluid's resistance to flow. + + + + + + + electrical potential between two points. **DEPRECATED** in *Version + 1.6*. Replaced by `VOLTAGE_AC` and `VOLTAGE_DC`. + + + + + + + apparent power in an electrical circuit, equal to the product of + root-mean-square (RMS) voltage and RMS current (commonly referred to + as VA). + + + + + + + reactive power in an AC electrical circuit (commonly referred to as + VAR). + + + + + + + fluid volume of an object or container. + + + + + + + geometric volume of an object or container. + + + + + + + power flowing through or dissipated by an electrical circuit or + piece of equipment. + + + + + + + electrical current that reverses direction at regular short + intervals. + + + + + + + electric current flowing in one direction only. + + + + + + + electrical potential between two points in an electrical circuit in + which the current periodically reverses direction. + + + + + + + electrical potential between two points in an electrical circuit in + which the current is unidirectional. + + + + + + + dimension of an entity relative to the X direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Y direction of the referenced + coordinate system. + + + + + + + dimension of an entity relative to the Z direction of the referenced + coordinate system. + + + + + + + dimension of a diameter. + + + + + + + angular position of a plane or vector relative to a {{term(cartesian + coordinate system)}} + + + + + + + amount of water vapor present expressed as a percent to reach + saturation at the same temperature. + + + + + + + amount of water vapor expressed in grams per cubic meter. + + + + + + + ratio of the water vapor present over the total weight of the water + vapor and air present expressed as a percent. + + + + + + + average rate of change of values for data items in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + average rate of change of values for assets in the MTConnect + streams. The average is computed over a rolling window defined by + the implementation. + + + + + + + change of pressure per unit time. + + + + + + + negative rate of change of velocity. + + + + + + + negative rate of change of angular velocity. + + + + + + + force per unit area measured relative to a vacuum. + + + + + + + percentage open where 100% is fully open and 0% is fully closed. + + + + + + + temperature at which moisture begins to condense, corresponding to + saturation for a given absolute humidity. + + + + + + + force relative to earth's gravity. + + + + + + + acceleration relative to Earth's gravity of 9.80665 + `METER/SECOND^2`. + + + + + + + maximum rated charge a battery is capable of maintaining based on + the battery discharging at a specified current over a specified time + period. + + + + + + + value of current being drawn from the {{block(Component)}}. + + + + + + + value of the current being supplied to the {{block(Component)}} for + the purpose of charging. + + + + + + + value of the battery's present capacity expressed as a + percentage of the battery's maximum rated capacity. + + + + + + + difference between actual and commanded position at the end of a + motion. + + + + + + + difference between actual and commanded position at any specific + point in time during a motion. + + + + + + + difference between the commanded encoder/resolver position, and the + actual encoder/resolver position when motion is complete. + + + + + + + angular difference between the commanded encoder/resolver position, + and the actual encoder/resolver position when motion is complete. + + + + + + + difference between the commanded encoder/resolver position and the + actual encoder/resolver position at any specified point in time + during a motion. + + + + + + + angular difference between the commanded encoder/resolver position + and the actual encoder/resolver position at any specified point in + time during a motion. + + + + + + + absolute value of the change in position along a vector. + + + + + + + absolute value of the change in angular position around a vector + + + + + + + point in a {{term(cartesian coordinate system)}}. + + + + + + + set of axes currently associated with a {{block(Path)}} or + {{block(Controller)}}. + + + + + + + operational state of an apparatus for moving or controlling a + mechanism or system. + + + + + + + **DEPRECATED:** Replaced with `CONDITION` category data items in + Version 1.1.0. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been added or + changed. + + + + + + + {{block(assetId)}} of the {{term(Asset)}} that has been removed. + + + + + + + {{term(agent)}}'s ability to communicate with the data source. + + + + + + + describes the way the axes will be associated to each other. This is + used in conjunction with `COUPLED_AXES` to indicate the way they are + interacting. + + + + + + + value of a signal or calculation issued to adjust the feedrate of an + individual linear type axis. + + + + + + + state of the axis lockout function when power has been removed and + the axis is allowed to move freely. + + + + + + + state of a {{block(Linear)}} or {{block(Rotary)}} component + representing an axis. + + + + + + + line of code or command being executed by a {{block(Controller)}} + entity. + + + + + + + total count of the number of blocks of program code that have been + executed since execution started. + + + + + + + state of an interlock function or control logic state intended to + prevent the associated {{block(Chuck)}} component from being + operated. + + + + + + + operating state of a mechanism that holds a part or stock material + during a manufacturing process. It may also represent a mechanism + that holds any other mechanism in place within a piece of equipment. + + + + + + + programmatic code being executed. **DEPRECATED** in *Version 1.1*. + + + + + + + operating state of a mechanism represented by a + {{block(Composition)}} entity. + + + + + + + current mode of the {{block(Controller)}} component. + + + + + + + setting or operator selection that changes the behavior of a piece + of equipment. + + + + + + + set of associated axes. + + + + + + + time and date code associated with a material or other physical + item. + + + + + + + identifier of another piece of equipment that is temporarily + associated with a component of this piece of equipment to perform a + particular function. + + + + + + + direction of motion. + + + + + + + operational state of a {{block(Door)}} component or composition + element. + + + + + + + state of the emergency stop signal for a piece of equipment, + controller path, or any other component or subsystem of a piece of + equipment. + + + + + + + indication of whether the end of a piece of bar stock being feed by + a bar feeder has been reached. + + + + + + + indication that a piece of equipment, or a sub-part of a piece of + equipment, is performing specific types of activities. + + + + + + + operating state of a {{block(Component)}}. + + + + + + + current intended production status of the {{block(Component)}}. + + + + + + + hardness of a material. + + + + + + + current line of code being executed. **DEPRECATED** in *Version + 1.4.0*. + + + + + + + identifier for a {{block(Block)}} of code in a {{block(Program)}}. + + + + + + + position of a block of program code within a control program. + + + + + + + identifier of a material used or consumed in the manufacturing + process. + + + + + + + identifies the layers of material applied to a part or product as + part of an additive manufacturing process. + + + + + + + information to be transferred from a piece of equipment to a client + software application. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + identifier for a pallet. + + + + + + + aggregate count of parts. + + + + + + + indication designating whether a part or work piece has been + detected or is present. + + + + + + + identifier of a part in a manufacturing operation. + + + + + + + identifier of a part or product moving through the manufacturing + process. **DEPRECATED** in *Version 1.7*. `PART_NUMBER` is now a + `subType` of `PART_KIND_ID`. + + + + + + + value of a signal or calculation issued to adjust the feedrate for + the axes associated with a {{block(Path)}} component that may + represent a single axis or the coordinated movement of multiple + axes. + + + + + + + describes the operational relationship between a {{block(Path)}} + entity and another {{block(Path)}} entity for pieces of equipment + comprised of multiple logical groupings of controlled axes or other + logical operations. + + + + + + + indication of the status of the source of energy for an entity to + allow it to perform its intended function or the state of an + enabling signal providing permission for the entity to perform its + functions. + + + + + + + status of the {{block(Component)}}. **DEPRECATED** in *Version + 1.1.0*. + + + + + + + time and date associated with an activity or event. + + + + + + + name of the logic or motion program being executed by the + {{block(Controller)}} component. + + + + + + + comment or non-executable statement in the control program. + + + + + + + indication of the status of the {{block(Controller)}} components + program editing mode. A program may be edited while another is + executed. + + + + + + + name of the program being edited. This is used in conjunction with + {{block(ProgramEdit)}} when in `ACTIVE` state. + + + + + + + non-executable header section of the control program. + + + + + + + {{term(URI)}} for the source file associated with + {{block(Program)}}. + + + + + + + defines whether the logic or motion program defined by + {{block(Program)}} is being executed from the local memory of the + controller or from an outside source. + + + + + + + indication of the nesting level within a control program that is + associated with the code or instructions that is currently being + executed. + + + + + + + current operating mode for a {{block(Rotary)}} type axis. + + + + + + + percentage change to the velocity of the programmed velocity for a + {{block(Rotary)}} axis. + + + + + + + serial number associated with a {{block(Component)}}, + {{block(Asset)}}, or {{block(Device)}}. + + + + + + + indication of the status of the spindle for a piece of equipment + when power has been removed and it is free to rotate. + + + + + + + identifier of an individual tool asset. + + + + + + + identifier for the tool group associated with a specific tool. + Commonly used to designate spare tools. + + + + + + + identifier of the tool currently in use for a given `Path`. + **DEPRECATED** in *Version 1.2.0*. See `TOOL_ASSET_ID`. + + + + + + + identifier assigned by the {{block(Controller)}} component to a + cutting tool when in use by a piece of equipment. + + + + + + + reference to the tool offset variables applied to the active cutting + tool. + + + + + + + identifier of the person currently responsible for operating the + piece of equipment. + + + + + + + data whose meaning may change over time due to changes in the + operation of a piece of equipment or the process being executed on + that piece of equipment. + + + + + + + indication of the reason that {{block(Execution)}} is reporting a + value of `WAIT`. + + + + + + + identifier for the type of wire used as the cutting mechanism in + Electrical Discharge Machining or similar processes. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. **DEPRECATION WARNING**: Recommend using + `FIXTURE_ID` instead. + + + + + + + reference to offset variables for a work piece or part. + + + + + + + Operating System (OS) of a {{block(Component)}}. + + + + + + + embedded software of a {{block(Component)}} . + + + + + + + application on a {{block(Component)}}. + + + + + + + software library on a {{block(Component)}} + + + + + + + hardware of a {{block(Component)}}. + + + + + + + network details of a {{block(Component)}}. + + + + + + + three space angular displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + three space linear displacement of an object or coordinate system + relative to a {{term(cartesian coordinate system)}}. + + + + + + + {{term(UUID)}} of new device added to an {{term(MTConnect Agent)}}. + + + + + + + {{term(UUID)}} of a device removed from an {{term(MTConnect + Agent)}}. + + + + + + + {{term(UUID)}} of the device whose {{term(metadata)}} has changed. + + + + + + + status of the connection between an {{term(adapter)}} and an + {{term(agent)}}. + + + + + + + originator’s software version of the {{term(adapter)}}. + + + + + + + {{term(URI)}} of the {{term(adapter)}}. + + + + + + + reference version of the MTConnect Standard supported by the + {{term(adapter)}}. + + + + + + + {{term(attachment)}} between a sensor and an entity. + + + + + + + state or condition of a part. + + + + + + + identifier of a process being executed by the device. + + + + + + + identifier given to link the individual occurrence to a group of + related occurrences, such as a process step in a process plan. + + + + + + + identifier given to link the individual occurrence to a class of + processes or process definition. + + + + + + + identifier given to a collection of individual parts. + + + + + + + identifier given to link the individual occurrence to a class of + parts, typically distinguished by a particular part design. + + + + + + + identifier given to a distinguishable, individual part. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. **DEPRECATION WARNING**. Recommend using + `CONTROL_LIMITS`. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. **DEPRECATION WARNING**. Recommend using + `SPECIFICATION_LIMITS`. + + + + + + + set of limits used to trigger warning or alarm indicators. + **DEPRECATION WARNING**. Recommend using `ALARM_LIMITS`. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, load materials, parts, or other items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, unload materials, parts, or other + items. + + + + + + + accumulation of the number of times an operation has attempted to, + or is planned to attempt to, transfer materials, parts, or other + items from one location to another. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, activate or be performed. + + + + + + + accumulation of the number of times a function has attempted to, or + is planned to attempt to, deactivate or cease. + + + + + + + accumulation of the number of times a cyclic function has attempted + to, or is planned to attempt to execute. + + + + + + + state of a valve is one of open, closed, or transitioning between + the states. + + + + + + + state or operating mode of a {{block(Lock)}}. + + + + + + + particular condition of the process occurrence at a specific time. + + + + + + + particular condition of the part occurrence at a specific time. + + + + + + + state of {{block(Component)}} or {{block(Composition)}} that + describes the automatic or manual operation of the entity. + + + + + + + {{term(data set)}} of the number of {{termplural(Asset)}} of a given + type for a {{term(Device)}}. + + + + + + + actions or activities to be performed in support of a piece of + equipment. + + + + + + + identifier for the current workholding or part clamp in use by a + piece of equipment. + + + + + + + interpretation of `PART_COUNT`. + + + + + + + time provided by a timing device at a specific point in time. + + + + + + + name of the host computer supplying data. + + + + + + + number of the TCP/IP or UDP/IP port for the connection endpoint. + + + + + + + indication designating whether a leak has been detected. + + + + + + + present status of the battery. + + + + + + + {{term(UUID)}} of a {{term(feature)}}. {{cite(ISO 10303 AP + 242/239)}}. + + + + + + + detection result of a sensor. + + + + + + + {{block(Event)}} that represents a {{block(Component)}} where the + {{block(EntryDefinition)}} identifies the {{block(Component)}} and + the {{block(CellDefinition)}}s define the + {{block(Component)}}'s observed {{block(DataItem)}}s. + + + + + + + properties of each addressable work offset. + + + + + + + properties of each addressable tool offset. + + + + + + + assessing elements of a {{term(feature)}}. + + + + + + + {{term(UUID)}} of the {{term(characteristic)}}. + + + + + + + class of measurement being performed. {{cite(QIF 3:2018 Section + 6.3)}} + + + + + + + measurement based on the measurement type. + + + + + + + engineering units of the measurement. + + + + + + + pass/fail result of the measurement. + + + + + + + method used to compute {{term(standard uncertainty)}}. + + + + + + + {{term(uncertainty)}} specified by {{block(UncertaintyType)}}. + + + + + + + set of limits defining a range of values designating acceptable + performance for a variable. + + + + + + + set of limits used to indicate whether a process variable is stable + and in control. + + + + + + + set of limits used to trigger warning or alarm indicators. + + + + + + + references the {{block(CuttingToolLifeCycle)}} + {{block(CuttingItem)}} index related to the + {{property(CuttingItem::indices)}} of the currently active cutting + tool edge. + + + + + + + structured information that allows the unambiguous determination of + an object for purposes of identification and location. {{cite(ISO + 19160-4:2017)}} + + + + + + + active energy source for the {{block(Component)}}. + + + + + + + textual description of the location of an object or activity. + + + + + + + dimension between two surfaces of an object, usually the dimension + of smallest measure, for example an additive layer, or a depth of + cut. + + + + + + + absolute geographic location defined by two coordinates, longitude + and latitude and an elevation. + + + + + + + indication that the piece of equipment has experienced a + communications failure. + + + + + + + indication that the value of the data associated with a measured + value or a calculation is outside of an expected range. + + + + + + + indication that an error occurred in the logic program or + programmable logic controller (PLC) associated with a piece of + equipment. + + + + + + + indication that an error occurred in the motion program associated + with a piece of equipment. + + + + + + + general purpose indication associated with an electronic component + of a piece of equipment or a controller that represents a fault that + is not associated with the operator, program, or hardware. + + + + + + + indication of a fault associated with an actuator. + + + + + + + operational state of an {{block(Interface)}}. + + + + + + + operating state of the service to advance material or feed product + to a piece of equipment from a continuous or bulk source. + + + + + + + operating state of the service to change the type of material or + product being loaded or fed to a piece of equipment. + + + + + + + operating state of the service to remove or retract material or + product. + + + + + + + operating state of the service to change the part or product + associated with a piece of equipment to a different part or product. + + + + + + + operating state of the service to load a piece of material or + product. + + + + + + + operating state of the service to unload a piece of material or + product. + + + + + + + operating state of the service to open a chuck. + + + + + + + operating state of the service to open a door. + + + + + + + operating state of the service to close a chuck. + + + + + + + operating state of the service to close a door. + + + + + + + A user variable + + + + + + + + + The types of measurements available + + + + + + + + Extended tyoe for The sub-types for a measurement + + + + + + + + + + The sub-types for a measurement + + + + + + + relating to or derived in the simplest manner from the fundamental + units or measurements. + + + + + + + indication of the operating state of a mechanism. + + + + + + + measured or reported value of an {{term(observation)}}. + + + + + + + all actions, items, or activities being counted independent of the + outcome. + + + + + + + measurement of alternating voltage or current. If not specified + further in statistic, defaults to RMS voltage. **DEPRECATED** in + *Version 1.6*. + + + + + + + A-Scale weighting factor on the frequency scale. + + + + + + + when multiple locations on a piece of bar stock being feed by a bar + feeder are referenced as the indication of whether the end of that + piece of bar stock has been reached. + + + + + + + actions, items, or activities being counted that do not conform to + specification or expectation. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + B-Scale weighting factor on the frequency scale. + + + + + + + directive value including adjustments such as an offset or + overrides. + + + + + + + amount of material consumed from an object or container during a + manufacturing process. + + + + + + + state of the enabling signal or control logic that enables or + disables the function or operation of the entity. + + + + + + + C-Scale weighting factor on the frequency scale. + + + + + + + elapsed time of a temporary halt of action. + + + + + + + DC current or voltage. **DEPRECATED** in *Version 1.6*. + + + + + + + setting or operator selection used to execute a test mode to confirm + the execution of machine functions. + + + + + + + D-Scale weighting factor on the frequency scale. + + + + + + + relating to the expiration or end of useful life for a material or + other physical item. + + + + + + + relating to the first use of a material or other physical item. + + + + + + + actions, items, or activities being counted that conform to + specification or expectation. + + + + + + + relating to or derived from the last {{term(observation)}}. + + + + + + + relating to momentary activation of a function or a movement. + **DEPRECATION WARNING**: May be deprecated in the future. + + + + + + + indication of the position of a mechanism that may move in a lateral + direction. + + + + + + + scale to measure the elasticity of a surface. + + + + + + + reference to a length type tool offset variable. + + + + + + + state of the power source. + + + + + + + direction of motion of a linear motion. + + + + + + + indication that the subparts of a piece of equipment are under load. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + relating to the primary logic or motion program currently being + executed. + + + + + + + relating to maintenance on the piece of equipment. + + + + + + + indication of the state of an operator controlled interlock that can + inhibit the ability to initiate an unclamp action of an + electronically controlled chuck. + + + + + + + related to the production of a material or other physical item. + + + + + + + maximum value. + + + + + + + minimum value. + + + + + + + scale to measure the resistance to scratching of a surface. + + + + + + + indication of the open or closed state of a mechanism. + + + + + + + no weighting factor on the frequency scale. + + + + + + + piece of equipment that is powered or performing any activity. + + + + + + + relating to the person currently responsible for operating the piece + of equipment. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + overridden value. + + + + + + + piece of equipment is powered and functioning or + {{block(Component)}} that are required to remain on are powered. + + + + + + + main or principle. + + + + + + + position provided by a measurement probe. **DEPRECATION WARNING**: + May be deprecated in the future. + + + + + + + relating to production of a part or product on a piece of equipment. + + + + + + + directive value without offsets and adjustments. + + + + + + + reference to a radial type tool offset variable. + + + + + + + performing an operation faster or in less time than nominal rate. + + + + + + + remaining measure or count of an action, object or activity. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + direction of a rotary motion using the right hand rule convention. + + + + + + + identity of a control program that is used to specify the order of + execution of other programs. + + + + + + + relating to the preparation of a piece of equipment for production + or restoring the piece of equipment to a neutral state after + production. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + standard measure of an object or an action. + + + + + + + boundary when an activity or an event commences. + + + + + + + indication of the activation state of a mechanism represented by a + {{block(Composition)}}. + + + + + + + goal of the operation or process. + + + + + + + relating to the end or completion of an activity or event. + + + + + + + setting or operator selection that changes the behavior of the + controller on a piece of equipment. + + + + + + + remaining usable measure of an object or action. + + + + + + + indication of the position of a mechanism that may move in a + vertical direction. + + + + + + + scale to measure the resistance to deformation of a surface. + + + + + + + piece of equipment performing any activity, the equipment is active + and performing a function under load or not. + + + + + + + IPV4 network address of the {{block(Component)}}. + + + + + + + IPV6 network address of the {{block(Component)}}. + + + + + + + Gateway for the {{block(Component)}} network. + + + + + + + SubNet mask for the {{block(Component)}} network. + + + + + + + layer2 Virtual Local Network (VLAN) ID for the {{block(Component)}} + network. + + + + + + + Media Access Control Address. The unique physical address of the + network hardware. + + + + + + + identifies whether the connection type is wireless. + + + + + + + license code to validate or activate the hardware or software. + + + + + + + version of the hardware or software. + + + + + + + date the hardware or software was released for general use. + + + + + + + date the hardware or software was installed. + + + + + + + corporate identity for the maker of the hardware or software. + + + + + + + universally unique identifier as specified in ISO 11578 or RFC 4122. + + + + + + + serial number that uniquely identifies a specific part. + + + + + + + material that is used to produce parts. + + + + + + + group of parts tracked as a lot. + + + + + + + group of parts produced in a batch. + + + + + + + material heat number. + + + + + + + particular part design or model. + + + + + + + group of parts having similarities in geometry, manufacturing + process, and/or functions. + + + + + + + word or set of words by which a part is known, addressed, or + referred to. + + + + + + + step in the process plan that this occurrence corresponds to. + + + + + + + process plan that a process occurrence belongs to. + + + + + + + authorization of a process occurrence. + + + + + + + word or set of words by which a process being executed (process + occurrence) by the device is known, addressed, or referred to. + + + + + + + reference to a ISO 10303 Executable. + + + + + + + associated with the completion of an activity or event. + + + + + + + relating to logic or motion program currently executing. + + + + + + + actions or activities that were attempted , but failed to complete + or resulted in an unexpected or unacceptable outcome. + + + + + + + actions or activities that were attempted, but terminated before + they could be completed. + + + + + + + boundary when an activity or an event terminates. + + + + + + + amount discarded. + + + + + + + amount included in the {{term(part)}}. + + + + + + + {{term(request)}} by an {{block(Interface)}} for a task. + + + + + + + {{term(response)}} by an {{block(Interface)}} to a {{term(request)}} + for a task. + + + + + + + phase or segment of a recipe or program. + + + + + + + phase of a recipe process. + + + + + + + process as part of product production; can be a subprocess of a + larger process. + + + + + + + step of a discrete manufacturing process. + + + + + + + observed as a binary data type. + + + + + + + observed as a boolean data type. + + + + + + + observed as a set containing a restricted number of discrete values + where each discrete value is named and unique. {{cite(ISO + 21961:2003, 013)}} + + + + + + + indicated by the presence or existence of something. + + + + + + + model info of the hardware or software. + + + + + + + + + The sub-types for a measurement + + + + + + + + Extended tyoe for Statistical operations on data + + + + + + + + + + Statistical operations on data + + + + + + + mathematical average value calculated for the data item during the + calculation period. + + + + + + + **DEPRECATED** in *Version 1.6*. ~~A measure of the + "peakedness" of a probability distribution; i.e., the + shape of the distribution curve.~~ + + + + + + + maximum or peak value recorded for the data item during the + calculation period. + + + + + + + middle number of a series of numbers. + + + + + + + minimum value recorded for the data item during the calculation + period. + + + + + + + number in a series of numbers that occurs most often. + + + + + + + difference between the maximum and minimum value of a data item + during the calculation period. Also represents Peak-to-Peak + measurement in a waveform. + + + + + + + mathematical Root Mean Square (RMS) value calculated for the data + item during the calculation period. + + + + + + + statistical Standard Deviation value calculated for the data item + during the calculation period. + + + + + + + + + Statistical operations on data + + + + + + + + Extended tyoe for same as {{property(DataItem::units)}}. See + {{package(Device Information Model)}}. + + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + + + same as {{property(DataItem::units)}}. See {{package(Device Information + Model)}}. + + + + + + + + Extended tyoe for The units supported for the source equipment that can + be converted into MTC Units. + + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + amps. + + + + + + + degrees Celsius. + + + + + + + count of something. + + + + + + + sound level. + + + + + + + angle in degrees. + + + + + + + space-delimited, floating-point representation of the angular + rotation in degrees around the X, Y, and Z axes relative to a + cartesian coordinate system respectively in order as A, B, and C. If + any of the rotations is not known, it **MUST** be zero (0). + + + + + + + angular degrees per second. + + + + + + + angular acceleration in degrees per second squared. + + + + + + + frequency measured in cycles per second. + + + + + + + measurement of energy. + + + + + + + kilograms. + + + + + + + measurement of volume of a fluid. + + + + + + + liters per second. + + + + + + + measurement of tilt. + + + + + + + millimeters. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in millimeters. + + + + + + + millimeters per revolution. + + + + + + + millimeters per second. + + + + + + + acceleration in millimeters per second squared. + + + + + + + force in Newtons. + + + + + + + torque, a unit for force times distance. + + + + + + + measure of electrical resistance. + + + + + + + pressure in Newtons per square meter. + + + + + + + measurement of viscosity. + + + + + + + percentage. + + + + + + + measure of the acidity or alkalinity of a solution. + + + + + + + revolutions per minute. + + + + + + + measurement of time. + + + + + + + measurement of electrical conductivity. + + + + + + + volts. + + + + + + + measurement of the apparent power in an electrical circuit, equal to + the product of root-mean-square (RMS) voltage and RMS current + (commonly referred to as VA). + + + + + + + measurement of reactive power in an AC electrical circuit (commonly + referred to as VAR). + + + + + + + watts. + + + + + + + measurement of electrical energy, equal to one Joule. + + + + + + + gram per cubic meter. + + + + + + + geometric volume in millimeters. + + + + + + + change of geometric volume per second. + + + + + + + change in geometric volume per second squared. + + + + + + + milligram. + + + + + + + milligram per cubic millimeter. + + + + + + + milliliter. + + + + + + + counts per second. + + + + + + + pascal per second. + + + + + + + 3D Unit Vector. Space delimited list of three floating point + numbers. + + + + + + + revolutions per second squared. + + + + + + + rotational velocity in revolution per second. + + + + + + + gram. + + + + + + + acceleration in meters per second squared. + + + + + + + electric charge in coulombs (C). + + + + + + + geometric volume in meters. + + + + + + + geometric area in millimeters. + + + + + + + measure of viscosity. + + + + + + + rotational velocity in degrees per minute. + + + + + + + temperature in Fahrenheit. + + + + + + + feet. + + + + + + + feet per minute. + + + + + + + feet per second. + + + + + + + acceleration in feet per second squared. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in feet. + + + + + + + gallons per minute. + + + + + + + measurement of time in hours. + + + + + + + inches. + + + + + + + inches per minute. + + + + + + + inches per second. + + + + + + + acceleration in inches per second squared. + + + + + + + measure of torque in inch pounds. + + + + + + + point in space identified by X, Y, and Z positions and represented + by a space-delimited set of numbers each expressed in inches. + + + + + + + measurement of temperature. + + + + + + + measurement in kilowatt. + + + + + + + kilowatt hours which is 3.6 mega joules. + + + + + + + measurement of rate of flow of a fluid. + + + + + + + velocity in millimeters per minute. + + + + + + + measurement of time in minutes. + + + + + + + unsupported unit. + + + + + + + US pounds. + + + + + + + pressure in pounds per square inch (PSI). + + + + + + + angle in radians. + + + + + + + velocity in radians per minute. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + rotational acceleration in radian per second squared. + + + + + + + pressure in Bar. + + + + + + + pressure in Torr. + + + + + + + pressure in Millimeter of Mercury (mmHg). + + + + + + + pascal per minute. + + + + + + + $$MASS\times GRAVITATIONAL_ACCELERATION$$ (g) given in + `METER/SECOND^2`. + + + + + + + acceleration relative to earth's gravity given in + `METER/SECOND^2`. > Note 1 to entry: At different points on + Earth's surface, the free-fall acceleration ranges from 9.764 + to 9.834 m/s2 (Wikipedia: Gravitational Acceleration). The constant + can be customized depending on the location in the universe. > + Note 2 to entry: In the standard, it is assumed that Earth's + average value of gravitational acceleration is 9.90665 m/s2. + + + + + + + electric charge in ampere hour. + + + + + + + change of geometric volume in cubic foot per hour. + + + + + + + change of geometric volume in cubic foot per minute. + + + + + + + geometric area in inches. + + + + + + + geometric volume in feet. + + + + + + + inch per revolution. + + + + + + + + + The units supported for the source equipment that can be converted into + MTC Units. + + + + + + + + The coordinate system to be used for the position + + + + + + + unchangeable coordinate system that has machine zero as its origin. + + + + + + + coordinate system that represents the working area for a particular + workpiece whose origin is shifted within the `MACHINE` coordinate + system. If the `WORK` coordinates are not currently defined in the + piece of equipment, the `MACHINE` coordinates will be used. + + + + + + + + + Extended tyoe for The reset intervals + + + + + + + + + + The reset intervals + + + + + + + {{term(observation)}} of the {{block(DataItem)}} that is measuring + an action or operation is to be reset upon completion of that action + or operation. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 12-month period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 24-hour period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is not reset and + accumulates for the entire life of the piece of equipment. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset upon + completion of a maintenance event. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a monthly period. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset when + power was applied to the piece of equipment after a planned or + unplanned interruption of power has occurred. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a work shift. + + + + + + + {{term(observation)}} of the {{block(DataItem)}} is to be reset at + the end of a 7-day period. + + + + + + + + + The reset intervals + + + + + + + + + The document version + + + + + + + time the file was created. + + + + + + + Indicates that this was a test document + + + + + + + The unique instance identifier of this agent process + + + + + + + The sender of the message + + + + + + + A timestamp in 8601 format of the last update of the Device + information for any device + + + + + + + + The station id for this device + + + + + + + + indicates if the MTConnect Agent is validating against the normative + model. + + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the data + management within the {{term(agent)}}. + + + + + + + + + The size of the agent's buffer. + + + + + + + The next sequence number for subsequent requests + + + + + + + The last sequence number available from the agent + + + + + + + The first sequence number available from the agent + + + + + + + indicates if the MTConnect Agent is validating against the + normative model. + + + + + + + + + + root entity of an {{term(MTConnectStreams Response Document)}} that + contains the {{term(Observation Information Model)}} of one or more + {{block(Device)}} entities. + ![MTConnectStreams](figures/MTConnectStreams.png + "MTConnectStreams"){: width="0.8"} > Note: + Additional properties of {{block(MTConnectStreams)}} **MAY** be defined + for schema and namespace declaration. See {{sect(Schema and Namespace + Declaration Information)}} for an {{term(XML)}} example. + + + + + + + provides information from an {{term(agent)}} defining version + information, storage capacity, and parameters associated with the + data management within the {{term(agent)}}. + + + + + + + {{block(Streams)}} groups one or more {{block(DeviceStream)}} + entities. See {{package(Observation Information Model)}} for more + detail. + + + + + + + + + An events data + + + + + + + + The item's unique ID that references the data item id from probe + + + + + + + + An Condition code as defined by the component + + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been deprecated in the MTConnect Standard. + + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been extended and cannot be validated. + + + + + + + + indicates if the Observation is verifiable and is in accordance with the + normative definitions within the MTConnect Standard. + + + + + + + observation is not valid against the MTConnect Standard according to + the validation capabilities of the MTConnect Agent. + + + + + + + observation cannot be validated. + + + + + + + observation is valid against the MTConnect Standard. + + + + + + + + + {{block(Streams)}} groups one or more {{block(DeviceStream)}} entities. + See {{package(Observation Information Model)}} for more detail. + + + + + + + Description + + + + + + + + + Description + + + + + + + {{block(ComponentStream)}} {{termplural(organize)}} the + {{block(Observation)}} entities associated with the + {{block(Component)}}. See {{package(Observation Information Model)}} + for the {{block(ComponentStream)}} model. > Note 1 to entry: In + the {{term(XML)}} representation, {{block(ComponentStream)}} + entities **MUST NOT** appear in the {{term(MTConnectDevices Response + Document)}}. > Note 2 to entry: In the {{term(XML)}} + representation, {{block(ComponentStream)}} entities **MUST** appear + only in the {{term(MTConnectStreams Response Document)}}. + + + + + + + + identifier of the maintenance activity. + + + + + + + The unque identifier for this device + + + + + + + + {{block(ComponentStream)}} {{termplural(organize)}} the + {{block(Observation)}} entities associated with the + {{block(Component)}}. See {{package(Observation Information Model)}} for + the {{block(ComponentStream)}} model. > Note 1 to entry: In the + {{term(XML)}} representation, {{block(ComponentStream)}} entities **MUST + NOT** appear in the {{term(MTConnectDevices Response Document)}}. > + Note 2 to entry: In the {{term(XML)}} representation, + {{block(ComponentStream)}} entities **MUST** appear only in the + {{term(MTConnectStreams Response Document)}}. + + + + + + + {{block(Samples)}} groups one or more {{block(Sample)}} entities. + See {{sect(Sample)}}. + + + + + + + {{block(Events)}} groups one or more {{block(Event)}} entities. See + {{sect(Event)}}. + + + + + + + Description + + + + + + + + The id of the component (maps to the id from probe) + + + + + + + identifier of the maintenance activity. + + + + + + + The device manufacturer component name + + + + + + + Description + + + + + + + The unque identifier for this component + + + + + + + + {{block(Samples)}} groups one or more {{block(Sample)}} entities. See + {{sect(Sample)}}. + + + + + + + + + + {{block(Events)}} groups one or more {{block(Event)}} entities. See + {{sect(Event)}}. + + + + + + + + + + A collection of conditions + + + + + + + + + + The observation value for indeterminent data + + + + + + + Data is unavailable + + + + + + + + + + The events sequence number + + + + + + + The event subtype corresponding to the measurement subtype + + + + + + + The time the event occurred or recorded + + + + + + + identifier of the maintenance activity. + + + + + + + The unique identifier of the item being produced + + + + + + + The identifier of the sub-element this result is in reference to + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been deprecated in the MTConnect Standard. + + + + + + + indicates if the Observation has any property or controlled vocabulary + that has been extended and cannot be validated. + + + + + + + indicates if the Observation is verifiable and is in accordance with + the normative definitions within the MTConnect Standard. + + + + + + + + The target rate a value can be sampled + + + + + + + + The number of items in the list + + + + + + + + Common floating point sample value + + + + + + + + Common floating point sample value + + + + + + + + Description + + + + + + + The rate the waveform was sampled at, default back to the value given + in the data item + + + + + + + An optional indicator that the event or sample was reset + + + + + + + The statistical operation on this data + + + + + + + The number of seconds since the reset of the statistic + + + + + + + + Description + + + + + + + A sample with a single floating point value + + + + + + + + + + + + + + A sample with a single floating point value + + + + + + + A sample with a three tuple floating point value + + + + + + + + + + + + + + A sample with a three tuple floating point value + + + + + + + The abstract waveform + + + + + + + + The number of samples + + + + + + + + + + The abstract waveform + + + + + + + Description + + + + + + + + + + + + + + Description + + + + + + + {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ACCELERATION)}} + + + + + + + {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + Time series of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + Time series of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE)}} + + + + + + + {{def(SampleEnum::ANGLE)}} + + + + + + + + + + {{def(SampleEnum::ANGLE)}} + + + + + + + Time series of {{def(SampleEnum::ANGLE)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGLE)}} + + + + + + + {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + Time series of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + Time series of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + Time series of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + Time series of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + Time series of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + {{def(SampleEnum::CONCENTRATION)}} + + + + + + + Time series of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + Time series of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + Time series of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + Time series of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + {{def(SampleEnum::DENSITY)}} + + + + + + + + + + {{def(SampleEnum::DENSITY)}} + + + + + + + Time series of {{def(SampleEnum::DENSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::DENSITY)}} + + + + + + + {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + Time series of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + Time series of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + Time series of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + {{def(SampleEnum::FLOW)}} + + + + + + + + + + {{def(SampleEnum::FLOW)}} + + + + + + + Time series of {{def(SampleEnum::FLOW)}} + + + + + + + + + + Time series of {{def(SampleEnum::FLOW)}} + + + + + + + {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + {{def(SampleEnum::FREQUENCY)}} + + + + + + + Time series of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + Time series of {{def(SampleEnum::FREQUENCY)}} + + + + + + + {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + Time series of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + Time series of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + {{def(SampleEnum::LENGTH)}} + + + + + + + + + + {{def(SampleEnum::LENGTH)}} + + + + + + + Time series of {{def(SampleEnum::LENGTH)}} + + + + + + + + + + Time series of {{def(SampleEnum::LENGTH)}} + + + + + + + {{def(SampleEnum::LEVEL)}} + + + + + + + + + + {{def(SampleEnum::LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::LEVEL)}} + + + + + + + {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + Time series of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + Time series of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + {{def(SampleEnum::LOAD)}} + + + + + + + + + + {{def(SampleEnum::LOAD)}} + + + + + + + Time series of {{def(SampleEnum::LOAD)}} + + + + + + + + + + Time series of {{def(SampleEnum::LOAD)}} + + + + + + + {{def(SampleEnum::MASS)}} + + + + + + + + + + {{def(SampleEnum::MASS)}} + + + + + + + Time series of {{def(SampleEnum::MASS)}} + + + + + + + + + + Time series of {{def(SampleEnum::MASS)}} + + + + + + + {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + Time series of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Example + + + + + + + + + + Example + + + + + + + {{def(SampleEnum::PH)}} + + + + + + + + + + {{def(SampleEnum::PH)}} + + + + + + + Time series of {{def(SampleEnum::PH)}} + + + + + + + + + + Time series of {{def(SampleEnum::PH)}} + + + + + + + {{def(SampleEnum::POSITION)}} + + + + + + + + + + {{def(SampleEnum::POSITION)}} + + + + + + + Time series of {{def(SampleEnum::POSITION)}} + + + + + + + + + + Time series of {{def(SampleEnum::POSITION)}} + + + + + + + {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Time series of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + Time series of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Description + + + + + + + + + + Description + + + + + + + Time series of {{def(SampleEnum::PRESSURE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PRESSURE)}} + + + + + + + {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + Time series of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + Time series of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + {{def(SampleEnum::RESISTANCE)}} + + + + + + + Time series of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + Time series of {{def(SampleEnum::RESISTANCE)}} + + + + + + + {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + Time series of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + Time series of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + Time series of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + Time series of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + {{def(SampleEnum::STRAIN)}} + + + + + + + + + + {{def(SampleEnum::STRAIN)}} + + + + + + + Time series of {{def(SampleEnum::STRAIN)}} + + + + + + + + + + Time series of {{def(SampleEnum::STRAIN)}} + + + + + + + {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + {{def(SampleEnum::TEMPERATURE)}} + + + + + + + Time series of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + Time series of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + {{def(SampleEnum::TENSION)}} + + + + + + + + + + {{def(SampleEnum::TENSION)}} + + + + + + + Time series of {{def(SampleEnum::TENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::TENSION)}} + + + + + + + {{def(SampleEnum::TILT)}} + + + + + + + + + + {{def(SampleEnum::TILT)}} + + + + + + + Time series of {{def(SampleEnum::TILT)}} + + + + + + + + + + Time series of {{def(SampleEnum::TILT)}} + + + + + + + {{def(SampleEnum::TORQUE)}} + + + + + + + + + + {{def(SampleEnum::TORQUE)}} + + + + + + + Time series of {{def(SampleEnum::TORQUE)}} + + + + + + + + + + Time series of {{def(SampleEnum::TORQUE)}} + + + + + + + {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + {{def(SampleEnum::VELOCITY)}} + + + + + + + Time series of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::VELOCITY)}} + + + + + + + {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + {{def(SampleEnum::VISCOSITY)}} + + + + + + + Time series of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::VISCOSITY)}} + + + + + + + {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE)}} + + + + + + + {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + Time series of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + Time series of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + {{def(SampleEnum::WATTAGE)}} + + + + + + + Time series of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::WATTAGE)}} + + + + + + + {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + Time series of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + Time series of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::X_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + Time series of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + Time series of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + {{def(SampleEnum::DIAMETER)}} + + + + + + + Time series of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + Time series of {{def(SampleEnum::DIAMETER)}} + + + + + + + {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + + {{def(SampleEnum::ORIENTATION)}} + + + + + + + {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + Time series of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + Time series of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + {{def(SampleEnum::DECELERATION)}} + + + + + + + Time series of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::DECELERATION)}} + + + + + + + {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + Time series of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + The force per unit area measured relative to a vacuum. + + + + + + + + + + The force per unit area measured relative to a vacuum. + + + + + + + Time series of The force per unit area measured relative to a vacuum. + + + + + + + + + + Time series of The force per unit area measured relative to a vacuum. + + + + + + + {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + {{def(SampleEnum::OPENNESS)}} + + + + + + + Time series of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + Time series of {{def(SampleEnum::OPENNESS)}} + + + + + + + {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + {{def(SampleEnum::DEW_POINT)}} + + + + + + + Time series of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + Time series of {{def(SampleEnum::DEW_POINT)}} + + + + + + + {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + + + + {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + Time series of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + Time series of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + Time series of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + Time series of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + Time series of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + Time series of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + Time series of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + Time series of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The displacement + vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + Time series of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + + {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + Integer event value + + + + + + + + Integer event value + + + + + + + + String event value + + + + + + + + DateTime String event value + + + + + + + + A list of axis names + + + + + + + + + + + + A list of axis for an event + + + + + + + + Common floating point event value + + + + + + + + Description + + + + + + + An optional indicator that the event or sample was reset + + + + + + + + Description + + + + + + + An unfaceted string event + + + + + + + + + + + + + + An unfaceted string event + + + + + + + An unfaceted string event + + + + + + + + + + + + + + An unfaceted string event + + + + + + + An unfaceted datetime event + + + + + + + + + + + + + + An unfaceted datetime event + + + + + + + An event with an integer value + + + + + + + + + + + + + + An event with an integer value + + + + + + + An event with an integer value + + + + + + + + + + + + + + An event with an integer value + + + + + + + An event with a three tuple floating point value + + + + + + + + + + + + + + An event with a three tuple floating point value + + + + + + + {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + + {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + Controlled vocabulary for ActuatorState + + + + + + + {{block(Actuator)}} is operating. + + + + + + + {{block(Actuator)}} is not operating. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + The type of asset + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + The type of asset + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + Controlled vocabulary for Availability + + + + + + + data source is active and capable of providing data. + + + + + + + data source is either inactive or not capable of providing data. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + + + + + + {{def(EventEnum::AVAILABILITY)}} + + + + + + + Controlled vocabulary for AxisCoupling + + + + + + + axes are physically connected to each other and operate as a single + unit. + + + + + + + axes are not physically connected to each other but are operating + together in lockstep. + + + + + + + axis is the master of the {{block(CoupledAxes)}}. + + + + + + + axis is a slave to the {{block(CoupledAxes)}}. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + + {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + Controlled vocabulary for AxisInterlock + + + + + + + axis lockout function is activated, power has been removed from the + axis, and the axis is allowed to move freely. + + + + + + + axis lockout function has not been activated, the axis may be + powered, and the axis is capable of being controlled by another + component. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + Controlled vocabulary for AxisState + + + + + + + axis is in its home position. + + + + + + + axis is in motion. + + + + + + + axis has been moved to a fixed position and is being maintained in + that position either electrically or mechanically. Action is + required to release the axis from this position. + + + + + + + axis is stopped. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::AXIS_STATE)}} + + + + + + + {{def(EventEnum::BLOCK)}} + + + + + + + + + + {{def(EventEnum::BLOCK)}} + + + + + + + {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + + {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + Controlled vocabulary for ChuckInterlock + + + + + + + chuck cannot be unclamped. + + + + + + + chuck can be unclamped. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + Controlled vocabulary for ChuckState + + + + + + + {{block(Chuck)}} is open to the point of a positive confirmation. + + + + + + + {{block(Chuck)}} is closed to the point of a positive confirmation. + + + + + + + {{block(Chuck)}} is not closed to the point of a positive + confirmation and not open to the point of a positive confirmation. + It is in an intermediate position. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::CHUCK_STATE)}} + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + + {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + Controlled vocabulary for ControllerMode + + + + + + + {{block(Controller)}} is configured to automatically execute a + program. + + + + + + + {{block(Controller)}} is not executing an active program. It is + capable of receiving instructions from an external source – + typically an operator. The {{block(Controller)}} executes operations + based on the instructions received from the external source. + + + + + + + operator can enter a series of operations for the + {{block(Controller)}} to perform. The {{block(Controller)}} will + execute this specific series of operations and then stop. + + + + + + + {{block(Controller)}} is operating in a mode that restricts the + active program from processing its next process step without + operator intervention. + + + + + + + {{block(Controller)}} is currently functioning as a programming + device and is not capable of executing an active program. + + + + + + + axes of the device are commanded to stop, but the spindle continues + to function. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + Controlled vocabulary for ControllerModeOverride + + + + + + + {{block(ControllerModeOverride)}} is in the `ON` state and the mode + override is active. + + + + + + + {{block(ControllerModeOverride)}} is in the `OFF` state and the mode + override is inactive. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + + + + + + {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + + {{def(EventEnum::COUPLED_AXES)}} + + + + + + + {{def(EventEnum::DATE_CODE)}} + + + + + + + + + + {{def(EventEnum::DATE_CODE)}} + + + + + + + {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + + {{def(EventEnum::DEVICE_UUID)}} + + + + + + + Controlled vocabulary for Direction + + + + + + + clockwise rotation using the right-hand rule. + + + + + + + counter-clockwise rotation using the right-hand rule. + + + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::DIRECTION)}} + + + + + + + + + + + + + + {{def(EventEnum::DIRECTION)}} + + + + + + + Controlled vocabulary for DoorState + + + + + + + {{block(Door)}} is open to the point of a positive confirmation. + + + + + + + {{block(Door)}} is closed to the point of a positive confirmation. + + + + + + + {{block(Door)}} is not closed to the point of a positive + confirmation and not open to the point of a positive confirmation. + It is in an intermediate position. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::DOOR_STATE)}} + + + + + + + Controlled vocabulary for EmergencyStop + + + + + + + emergency stop circuit is complete and the piece of equipment, + component, or composition is allowed to operate. + + + + + + + operation of the piece of equipment, component, or composition is + inhibited. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + + + + + + {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + Controlled vocabulary for EndOfBar + + + + + + + {{block(EndOfBar)}} has been reached. + + + + + + + {{block(EndOfBar)}} has not been reached. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + + + + + + {{def(EventEnum::END_OF_BAR)}} + + + + + + + Controlled vocabulary for EquipmentMode + + + + + + + equipment is functioning in the mode designated by the `subType`. + + + + + + + equipment is not functioning in the mode designated by the + `subType`. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + Controlled vocabulary for Execution + + + + + + + {{block(Component)}} is ready to execute instructions. It is + currently idle. + + + + + + + {{block(Component)}} is actively executing an instruction. + + + + + + + {{block(Component)}} suspends the execution of the program due to an + external signal. Action is required to resume execution. + + + + + + + motion of the active axes are commanded to stop at their current + position. + + + + + + + {{block(Component)}} program is not `READY` to execute. + + + + + + + command from the program has intentionally interrupted execution. + The {{block(Component)}} **MAY** have another state that indicates + if the execution is interrupted or the execution ignores the + interrupt instruction. + + + + + + + command from the program has intentionally interrupted execution. + Action is required to resume execution. + + + + + + + program completed execution. + + + + + + + {{block(Component)}} suspends execution while a secondary operation + executes. Execution resumes automatically once the secondary + operation completes. + + + + + + + program has been intentionally optionally stopped using an M01 or + similar code. **DEPRECATED** in *version 1.4* and replaced with + `OPTIONAL_STOP`. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::EXECUTION)}} + + + + + + + + + + + + + + {{def(EventEnum::EXECUTION)}} + + + + + + + Controlled vocabulary for FunctionalMode + + + + + + + {{block(Component)}} is currently producing product, ready to + produce product, or its current intended use is to be producing + product. + + + + + + + {{block(Component)}} is not currently producing product. It is being + prepared or modified to begin production of product. + + + + + + + {{block(Component)}} is not currently producing product. Typically, + it has completed the production of a product and is being modified + or returned to a neutral state such that it may then be prepared to + begin production of a different product. + + + + + + + {{block(Component)}} is not currently producing product. It is + currently being repaired, waiting to be repaired, or has not yet + been returned to a normal production status after maintenance has + been performed. + + + + + + + {{block(Component)}} is being used to prove-out a new process, + testing of equipment or processes, or any other active use that does + not result in the production of product. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + {{def(EventEnum::HARDNESS)}} + + + + + + + + + + {{def(EventEnum::HARDNESS)}} + + + + + + + {{def(EventEnum::LINE)}} + + + + + + + + + + {{def(EventEnum::LINE)}} + + + + + + + {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + + {{def(EventEnum::LINE_LABEL)}} + + + + + + + {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + + {{def(EventEnum::LINE_NUMBER)}} + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + + + + {{block(Resource)}} composed of material that is consumed or used by the + piece of equipment for production of parts, materials, or other types of + goods. + + + + + + + {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + + {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + {{def(EventEnum::MESSAGE)}} + + + + + + + + + + {{def(EventEnum::MESSAGE)}} + + + + + + + {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + + {{def(EventEnum::OPERATOR_ID)}} + + + + + + + {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + {{def(EventEnum::PALLET_ID)}} + + + + + + + {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + {{def(EventEnum::PART_COUNT)}} + + + + + + + Controlled vocabulary for PartDetect + + + + + + + part or work piece is detected or is present. + + + + + + + part or work piece is not detected or is not present. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_DETECT)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_DETECT)}} + + + + + + + {{def(EventEnum::PART_ID)}} + + + + + + + + + + {{def(EventEnum::PART_ID)}} + + + + + + + {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + + {{def(EventEnum::PART_NUMBER)}} + + + + + + + {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + + {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + Controlled vocabulary for PathMode + + + + + + + path is operating independently and without the influence of another + path. + + + + + + + path provides information or state values that influences the + operation of other {{block(DataItem)}} of similar type. + + + + + + + physical or logical parts which are not physically connected to each + other but are operating together. + + + + + + + axes associated with the path are mirroring the motion of the + `MASTER` path. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PATH_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::PATH_MODE)}} + + + + + + + Controlled vocabulary for PowerState + + + + + + + source of energy for an entity or the enabling signal providing + permission for the entity to perform its function(s) is present and + active. + + + + + + + source of energy for an entity or the enabling signal providing + permission for the entity to perform its function(s) is not present + or is disconnected. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::POWER_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::POWER_STATE)}} + + + + + + + Controlled vocabulary for PowerStatus + + + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::POWER_STATUS)}} + + + + + + + {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + + {{def(EventEnum::PROCESS_TIME)}} + + + + + + + {{def(EventEnum::PROGRAM)}} + + + + + + + + + + {{def(EventEnum::PROGRAM)}} + + + + + + + {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + Controlled vocabulary for ProgramEdit + + + + + + + {{block(Controller)}} is in the program edit mode. + + + + + + + {{block(Controller)}} is capable of entering the program edit mode + and no function is inhibiting a change to that mode. + + + + + + + {{block(Controller)}} is being inhibited by a function from entering + the program edit mode. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + Controlled vocabulary for ProgramLocationType + + + + + + + managed by the controller. + + + + + + + not managed by the controller. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is not + defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + + {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is not + defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + Controlled vocabulary for RotaryMode + + + + + + + axis is functioning as a spindle. + + + + + + + axis is configured to index. + + + + + + + position of the axis is being interpolated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::ROTARY_MODE)}} + + + + + + + {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command represents a + percentage change to the velocity calculated by a logic or motion + program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + + {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command represents a + percentage change to the velocity calculated by a logic or motion + program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + + {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + Controlled vocabulary for SpindleInterlock + + + + + + + power has been removed and the spindle cannot be operated. + + + + + + + spindle has not been deactivated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + + + + + + {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + + {{def(EventEnum::TOOL_GROUP)}} + + + + + + + {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + {{def(EventEnum::TOOL_ID)}} + + + + + + + {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + + {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + {{def(EventEnum::USER)}} + + + + + + + + + + {{def(EventEnum::USER)}} + + + + + + + {{def(EventEnum::VARIABLE)}} + + + + + + + + + + {{def(EventEnum::VARIABLE)}} + + + + + + + Controlled vocabulary for WaitState + + + + + + + execution is waiting while the equipment is powering up and is not + currently available to begin producing parts or products. + + + + + + + execution is waiting while the equipment is powering down but has + not fully reached a stopped state. + + + + + + + execution is waiting while one or more discrete workpieces are being + loaded. + + + + + + + execution is waiting while one or more discrete workpieces are being + unloaded. + + + + + + + execution is waiting while a tool or tooling is being loaded. + + + + + + + execution is waiting while a tool or tooling is being unloaded. + + + + + + + execution is waiting while material is being loaded. + + + + + + + execution is waiting while material is being unloaded. + + + + + + + execution is waiting while another process is completed before the + execution can resume. + + + + + + + execution is waiting while the equipment is pausing but the piece of + equipment has not yet reached a fully paused state. + + + + + + + execution is waiting while the equipment is resuming the production + cycle but has not yet resumed execution. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::WAIT_STATE)}} When {{property(Execution::result)}} is + not `WAIT`, {{property(Observation::isUnavailable)}} of + {{block(WaitState)}} **MUST** be `true`. + + + + + + + + + + + + + + {{def(EventEnum::WAIT_STATE)}} When {{property(Execution::result)}} is + not `WAIT`, {{property(Observation::isUnavailable)}} of + {{block(WaitState)}} **MUST** be `true`. + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + + + + leaf {{block(Component)}} composed of a string like piece or filament of + relatively rigid or flexible material provided in a variety of + diameters. + + + + + + + {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + + {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + + {{def(EventEnum::WORK_OFFSET)}} + + + + + + + {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + + {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + {{def(EventEnum::FIRMWARE)}} + + + + + + + + + + {{def(EventEnum::FIRMWARE)}} + + + + + + + {{def(EventEnum::APPLICATION)}} + + + + + + + + + + {{def(EventEnum::APPLICATION)}} + + + + + + + {{def(EventEnum::LIBRARY)}} + + + + + + + + + + {{def(EventEnum::LIBRARY)}} + + + + + + + {{def(EventEnum::HARDWARE)}} + + + + + + + + + + {{def(EventEnum::HARDWARE)}} + + + + + + + {{def(EventEnum::NETWORK)}} + + + + + + + + + + {{def(EventEnum::NETWORK)}} + + + + + + + rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + + rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + + + + translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + Controlled vocabulary for PartStatus + + + + + + + part conforms to given requirements. + + + + + + + part does not conform to some given requirements. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_STATUS)}} If unique identifier is given, part + status is for that individual. If group identifier is given without a + unique identifier, then the status is assumed to be for the whole group. + + + + + + + + + + + + + + {{def(EventEnum::PART_STATUS)}} If unique identifier is given, part + status is for that individual. If group identifier is given without a + unique identifier, then the status is assumed to be for the whole group. + + + + + + + {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + + {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + {{def(EventEnum::PART_KIND_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_KIND_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + + {{def(EventEnum::ADAPTER_URI)}} + + + + + + + {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + + {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + Controlled vocabulary for ConnectionStatus + + + + + + + no connection at all. + + + + + + + {{term(agent)}} is waiting for a connection request from an + {{term(adapter)}}. + + + + + + + open connection. The normal state for the data transfer phase of the + connection. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + + {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + + {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + + {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + condensed message digest from a secure one-way hash function. + + + + + + + + + + {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + + {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + + {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + {{def(EventEnum::PART_GROUP_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_GROUP_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::PART_UNIQUE_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + + + + {{def(EventEnum::PART_UNIQUE_ID)}} If no {{property(DataItem::subType)}} + is specified, `UUID` is default. + + + + + + + {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + + {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + + {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + + {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + + {{def(EventEnum::LOAD_COUNT)}} + + + + + + + Controlled vocabulary for PartProcessingState + + + + + + + part occurrence is not actively being processed, but the processing + has not ended. Processing requirements exist that have not yet been + fulfilled. This is the default entry state when the part occurrence + is originally received. In some cases, the part occurrence may + return to this state while it waits for additional processing to be + performed. + + + + + + + part occurrence is actively being processed. + + + + + + + part occurrence is no longer being processed. A general state when + the reason for termination is unknown. + + + + + + + part occurrence has completed processing successfully. + + + + + + + process has been stopped during the processing. The part occurrence + will require special treatment. + + + + + + + processing of the part occurrence has come to a premature end. + + + + + + + terminal state when the part occurrence has been removed from the + equipment by an external entity and it no longer exists at the + equipment. + + + + + + + part occurrence has been skipped for processing on the piece of + equipment. + + + + + + + part occurrence has been processed completely. However, the + processing may have a problem. + + + + + + + part occurrence is waiting for transit. + + + + + + + part occurrence is being transported to its destination. + + + + + + + part occurrence has been placed at its designated destination. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + Controlled vocabulary for ProcessState + + + + + + + device is preparing to execute the process occurrence. + + + + + + + process occurrence is ready to be executed. + + + + + + + process occurrence is actively executing. + + + + + + + process occurrence is now finished. + + + + + + + process occurrence has been stopped and may be resumed. + + + + + + + process occurrence has come to a premature end and cannot be + resumed. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::PROCESS_STATE)}} + + + + + + + Controlled vocabulary for ValveState + + + + + + + {{block(ValveState)}} where flow is allowed and the aperture is + static. > Note: For a binary value, `OPEN` indicates the valve + has the maximum possible aperture. + + + + + + + valve is transitioning from a `CLOSED` state to an `OPEN` state. + + + + + + + {{block(ValveState)}} where flow is not possible, the aperture is + static, and the valve is completely shut. + + + + + + + valve is transitioning from an `OPEN` state to a `CLOSED` state. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::VALVE_STATE)}} + + + + + + + Controlled vocabulary for LockState + + + + + + + mechanism is engaged and preventing the associated + {{block(Component)}} from being opened or operated. + + + + + + + mechanism is disengaged and the associated {{block(Component)}} is + able to be opened or operated. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::LOCK_STATE)}} + + + + + + + {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + + {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + + {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + Controlled vocabulary for OperatingMode + + + + + + + automatically execute instructions from a recipe or program. > + Note: Setpoint comes from a recipe. + + + + + + + execute instructions from an external agent or person. > Note 1 + to entry: Valve or switch is manipulated by an agent/person. > + Note 2 to entry: Direct control of the PID output. % of the range: A + user manually sets the % output, not the setpoint. + + + + + + + executes a single instruction from a recipe or program. > Note 1 + to entry: Setpoint is entered and fixed, but the PID is controlling. + > Note 2 to entry: Still goes through the PID control system. + > Note 3 to entry: Manual fixed entry from a recipe. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + + + + + + {{def(EventEnum::OPERATING_MODE)}} + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + + {{def(EventEnum::ASSET_COUNT)}} + + + + + + + {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + + {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + + {{def(EventEnum::FIXTURE_ID)}} + + + + + + + Controlled vocabulary for PartCountType + + + + + + + count is of individual items. + + + + + + + pre-specified group of items. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + + {{def(EventEnum::CLOCK_TIME)}} + + + + + + + {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + + {{def(EventEnum::NETWORK_PORT)}} + + + + + + + {{def(EventEnum::HOST_NAME)}} + + + + + + + + + + {{def(EventEnum::HOST_NAME)}} + + + + + + + Controlled vocabulary for LeakDetect + + + + + + + leak is currently being detected. + + + + + + + leak is currently not being detected. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + + + + + + {{def(EventEnum::LEAK_DETECT)}} + + + + + + + Controlled vocabulary for BatteryState + + + + + + + {{block(Component)}} is at it's maximum rated charge level. + + + + + + + {{block(Component)}}'s charge is increasing. + + + + + + + {{block(Component)}}'s charge is decreasing. + + + + + + + {{block(Component)}} is at it's minimum charge level. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + + + + + + {{def(EventEnum::BATTERY_STATE)}} + + + + + + + {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + + {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + + {{def(EventEnum::SENSOR_STATE)}} + + + + + + + tabular {{def(EventEnum::COMPONENT_DATA)}} If the {{block(Component)}} + multiplicity can be determined, the device model **MUST** use a fixed + set of {{block(Component)}}s. {{block(ComponentData)}} **MUST** provide + a {{block(DataItem)}} {{block(Definition)}}. + + + + + + + + + + tabular {{def(EventEnum::COMPONENT_DATA)}} If the {{block(Component)}} + multiplicity can be determined, the device model **MUST** use a fixed + set of {{block(Component)}}s. {{block(ComponentData)}} **MUST** provide + a {{block(DataItem)}} {{block(Definition)}}. + + + + + + + tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + + tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + + tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + tabular representation of {{def(EventEnum::FEATURE_MEASUREMENT)}} + {{block(FeatureMeasurement)}} **MAY** include a {{term(characteristic)}} + in which case it **MAY** include a `CHARACTERISTIC_STATUS`. + + + + + + + + + + tabular representation of {{def(EventEnum::FEATURE_MEASUREMENT)}} + {{block(FeatureMeasurement)}} **MAY** include a {{term(characteristic)}} + in which case it **MAY** include a `CHARACTERISTIC_STATUS`. + + + + + + + {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, `RADIUS`, + `ANGLE`, `LENGTH`, etc. + + + + + + + + + + {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, `RADIUS`, + `ANGLE`, `LENGTH`, etc. + + + + + + + {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + + {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + + {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + Controlled vocabulary for CharacteristicStatus + + + + + + + measurement is within acceptable tolerances. + + + + + + + measurement is not within acceptable tolerances. + + + + + + + failed, but acceptable constraints achievable by utilizing + additional manufacturing processes. + + + + + + + measurement is indeterminate due to an equipment failure. + + + + + + + measurement cannot be determined. + + + + + + + measurement cannot be evaluated. + + + + + + + nominal provided without tolerance limits. {{cite(QIF 3:2018 + 5.10.2.6)}} + + + + + + + status of measurement cannot be determined. + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + + + + + + {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + Controlled vocabulary for UncertaintyType + + + + + + + {{term(combined standard uncertainty)}}. + + + + + + + {{term(standard uncertainty)}} using arithmetic mean or average the + observations. {{cite(JCGM 100:2008 4.2)}} + + + + + + + Value is indeterminate + + + + + + + + + {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + + + + + + {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + + {{def(EventEnum::UNCERTAINTY)}} + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + + + + See {{sect(AlarmLimits)}}. + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + + + + See {{sect(ControlLimits)}}. + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + + + + See {{sect(SpecificationLimits)}}. + + + + + + + {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + + {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + + {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + + {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + + {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + {{def(EventEnum::THICKNESS)}} + + + + + + + + + + {{def(EventEnum::THICKNESS)}} + + + + + + + {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + + {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + + {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + + {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + + {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + + {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + + {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + + {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + Controlled vocabulary for InterfaceState + + + + + + + {{block(Interface)}} is currently operational and performing as + expected. + + + + + + + {{block(Interface)}} is currently not operational. + + + + + + + Value is indeterminate + + + + + + + + + {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + + + + + + {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + Discrete of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + Discrete of {{def(EventEnum::PART_COUNT)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_ID)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + Discrete of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + Discrete of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + Discrete of {{def(EventEnum::PALLET_ID)}} + + + + + + + Discrete of {{def(EventEnum::MESSAGE)}} + + + + + + + + + + Discrete of {{def(EventEnum::MESSAGE)}} + + + + + + + Discrete of {{def(EventEnum::BLOCK)}} + + + + + + + + + + Discrete of {{def(EventEnum::BLOCK)}} + + + + + + + Constraints for Entry Values + + + + + + the key + + + + + + + an indicatore that the entry has been removed + + + + + + + + Constraints for Entry Values + + + + + + + DataSet of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + DataSet of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + DataSet of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + DataSet of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + DataSet of {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::AVAILABILITY)}} + + + + + + + DataSet of {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::AVAILABILITY)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_STATE)}} + + + + + + + DataSet of {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::AXIS_STATE)}} + + + + + + + DataSet of {{def(EventEnum::BLOCK)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::BLOCK)}} + + + + + + + DataSet of {{def(EventEnum::BLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::BLOCK)}} + + + + + + + DataSet of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + DataSet of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + DataSet of {{def(EventEnum::CODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CODE)}} + + + + + + + DataSet of {{def(EventEnum::CODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CODE)}} + + + + + + + DataSet of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + DataSet of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + DataSet of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + DataSet of {{def(EventEnum::DATE_CODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DATE_CODE)}} + + + + + + + DataSet of {{def(EventEnum::DATE_CODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DATE_CODE)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + DataSet of {{def(EventEnum::DIRECTION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DIRECTION)}} + + + + + + + DataSet of {{def(EventEnum::DIRECTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DIRECTION)}} + + + + + + + DataSet of {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DOOR_STATE)}} + + + + + + + DataSet of {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DOOR_STATE)}} + + + + + + + DataSet of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + DataSet of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + DataSet of {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::END_OF_BAR)}} + + + + + + + DataSet of {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::END_OF_BAR)}} + + + + + + + DataSet of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + DataSet of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + DataSet of {{def(EventEnum::EXECUTION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::EXECUTION)}} + + + + + + + DataSet of {{def(EventEnum::EXECUTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::EXECUTION)}} + + + + + + + DataSet of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + DataSet of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + DataSet of {{def(EventEnum::HARDNESS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::HARDNESS)}} + + + + + + + DataSet of {{def(EventEnum::HARDNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::HARDNESS)}} + + + + + + + DataSet of {{def(EventEnum::LINE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LINE)}} + + + + + + + DataSet of {{def(EventEnum::LINE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LINE)}} + + + + + + + DataSet of {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LINE_LABEL)}} + + + + + + + DataSet of {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LINE_LABEL)}} + + + + + + + DataSet of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + DataSet of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + + + + + + + + DataSet of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + DataSet of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + DataSet of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + DataSet of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + DataSet of {{def(EventEnum::MESSAGE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MESSAGE)}} + + + + + + + DataSet of {{def(EventEnum::MESSAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MESSAGE)}} + + + + + + + DataSet of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + DataSet of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + DataSet of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PALLET_ID)}} + + + + + + + DataSet of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PALLET_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::PART_DETECT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_DETECT)}} + + + + + + + DataSet of {{def(EventEnum::PART_DETECT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_DETECT)}} + + + + + + + DataSet of {{def(EventEnum::PART_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + DataSet of {{def(EventEnum::PATH_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PATH_MODE)}} + + + + + + + DataSet of {{def(EventEnum::PATH_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PATH_MODE)}} + + + + + + + DataSet of {{def(EventEnum::POWER_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::POWER_STATE)}} + + + + + + + DataSet of {{def(EventEnum::POWER_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::POWER_STATE)}} + + + + + + + DataSet of {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::POWER_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::POWER_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + DataSet of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + DataSet of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + DataSet of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + DataSet of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + DataSet of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + DataSet of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_ID)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_ID)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + DataSet of {{def(EventEnum::USER)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::USER)}} + + + + + + + DataSet of {{def(EventEnum::USER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::USER)}} + + + + + + + DataSet of {{def(EventEnum::VARIABLE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::VARIABLE)}} + + + + + + + DataSet of {{def(EventEnum::VARIABLE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::VARIABLE)}} + + + + + + + DataSet of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + DataSet of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + DataSet of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + + + + + + + + DataSet of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + DataSet of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + DataSet of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + DataSet of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + DataSet of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + DataSet of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + DataSet of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + DataSet of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + DataSet of {{def(EventEnum::FIRMWARE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::FIRMWARE)}} + + + + + + + DataSet of {{def(EventEnum::FIRMWARE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::FIRMWARE)}} + + + + + + + DataSet of {{def(EventEnum::APPLICATION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::APPLICATION)}} + + + + + + + DataSet of {{def(EventEnum::APPLICATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::APPLICATION)}} + + + + + + + DataSet of {{def(EventEnum::LIBRARY)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LIBRARY)}} + + + + + + + DataSet of {{def(EventEnum::LIBRARY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LIBRARY)}} + + + + + + + DataSet of {{def(EventEnum::HARDWARE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::HARDWARE)}} + + + + + + + DataSet of {{def(EventEnum::HARDWARE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::HARDWARE)}} + + + + + + + DataSet of {{def(EventEnum::NETWORK)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::NETWORK)}} + + + + + + + DataSet of {{def(EventEnum::NETWORK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::NETWORK)}} + + + + + + + DataSet of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + + + + + + DataSet of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + DataSet of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + DataSet of translations along X, Y, and Z axes are expressed as x,y, and + z respectively within a 3-dimensional vector. + + + + + + + + + + + + + + DataSet of translations along X, Y, and Z axes are expressed as x,y, and + z respectively within a 3-dimensional vector. + + + + + + + DataSet of translations along X, Y, and Z axes are expressed as x,y, and + z respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of translations along X, Y, and Z axes are expressed as x,y, and + z respectively within a 3-dimensional vector. + + + + + + + DataSet of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + DataSet of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + DataSet of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + DataSet of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + DataSet of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + DataSet of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + DataSet of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + DataSet of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + DataSet of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + DataSet of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + DataSet of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + DataSet of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + DataSet of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + DataSet of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + DataSet of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + DataSet of {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::VALVE_STATE)}} + + + + + + + DataSet of {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::VALVE_STATE)}} + + + + + + + DataSet of {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LOCK_STATE)}} + + + + + + + DataSet of {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LOCK_STATE)}} + + + + + + + DataSet of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + DataSet of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + DataSet of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + DataSet of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + DataSet of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + DataSet of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + DataSet of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + DataSet of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + DataSet of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + DataSet of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + DataSet of {{def(EventEnum::HOST_NAME)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::HOST_NAME)}} + + + + + + + DataSet of {{def(EventEnum::HOST_NAME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::HOST_NAME)}} + + + + + + + DataSet of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + DataSet of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + DataSet of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + DataSet of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + DataSet of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + DataSet of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + DataSet of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + DataSet of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + DataSet of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + + + + + + + + DataSet of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + DataSet of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + DataSet of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + + + + + + DataSet of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + DataSet of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + DataSet of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + + + + + + DataSet of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + DataSet of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + DataSet of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + + + + + + + + DataSet of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + DataSet of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + DataSet of See {{sect(AlarmLimits)}}. + + + + + + + + + + + + + + DataSet of See {{sect(AlarmLimits)}}. + + + + + + + DataSet of See {{sect(AlarmLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of See {{sect(AlarmLimits)}}. + + + + + + + DataSet of See {{sect(ControlLimits)}}. + + + + + + + + + + + + + + DataSet of See {{sect(ControlLimits)}}. + + + + + + + DataSet of See {{sect(ControlLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of See {{sect(ControlLimits)}}. + + + + + + + DataSet of See {{sect(SpecificationLimits)}}. + + + + + + + + + + + + + + DataSet of See {{sect(SpecificationLimits)}}. + + + + + + + DataSet of See {{sect(SpecificationLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of See {{sect(SpecificationLimits)}}. + + + + + + + DataSet of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + DataSet of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + DataSet of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + DataSet of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + DataSet of {{def(EventEnum::THICKNESS)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::THICKNESS)}} + + + + + + + DataSet of {{def(EventEnum::THICKNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::THICKNESS)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + DataSet of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + DataSet of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + DataSet of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + DataSet of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + DataSet of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE)}} + + + + + + + DataSet of {{def(SampleEnum::ANGLE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ANGLE)}} + + + + + + + DataSet of {{def(SampleEnum::ANGLE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ANGLE)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + DataSet of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + DataSet of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + DataSet of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + DataSet of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + DataSet of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + DataSet of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + DataSet of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + DataSet of {{def(SampleEnum::DENSITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DENSITY)}} + + + + + + + DataSet of {{def(SampleEnum::DENSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DENSITY)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + DataSet of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + DataSet of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + DataSet of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + DataSet of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + DataSet of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::FLOW)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FLOW)}} + + + + + + + DataSet of {{def(SampleEnum::FLOW)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FLOW)}} + + + + + + + DataSet of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FREQUENCY)}} + + + + + + + DataSet of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FREQUENCY)}} + + + + + + + DataSet of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + DataSet of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + DataSet of {{def(SampleEnum::LENGTH)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::LENGTH)}} + + + + + + + DataSet of {{def(SampleEnum::LENGTH)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::LENGTH)}} + + + + + + + DataSet of {{def(SampleEnum::LEVEL)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + DataSet of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + DataSet of {{def(SampleEnum::LOAD)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::LOAD)}} + + + + + + + DataSet of {{def(SampleEnum::LOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::LOAD)}} + + + + + + + DataSet of {{def(SampleEnum::MASS)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::MASS)}} + + + + + + + DataSet of {{def(SampleEnum::MASS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::MASS)}} + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + DataSet of Example + + + + + + + + + + + + + + DataSet of Example + + + + + + + DataSet of Example + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of Example + + + + + + + DataSet of {{def(SampleEnum::PH)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::PH)}} + + + + + + + DataSet of {{def(SampleEnum::PH)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::PH)}} + + + + + + + DataSet of {{def(SampleEnum::POSITION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::POSITION)}} + + + + + + + DataSet of {{def(SampleEnum::POSITION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::POSITION)}} + + + + + + + DataSet of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + DataSet of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + DataSet of Description + + + + + + + + + + + + + + DataSet of Description + + + + + + + DataSet of Description + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of Description + + + + + + + DataSet of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + DataSet of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + DataSet of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::RESISTANCE)}} + + + + + + + DataSet of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::RESISTANCE)}} + + + + + + + DataSet of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + DataSet of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + DataSet of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + DataSet of {{def(SampleEnum::STRAIN)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::STRAIN)}} + + + + + + + DataSet of {{def(SampleEnum::STRAIN)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::STRAIN)}} + + + + + + + DataSet of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + DataSet of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + DataSet of {{def(SampleEnum::TENSION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::TENSION)}} + + + + + + + DataSet of {{def(SampleEnum::TENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::TENSION)}} + + + + + + + DataSet of {{def(SampleEnum::TILT)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::TILT)}} + + + + + + + DataSet of {{def(SampleEnum::TILT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::TILT)}} + + + + + + + DataSet of {{def(SampleEnum::TORQUE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::TORQUE)}} + + + + + + + DataSet of {{def(SampleEnum::TORQUE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::TORQUE)}} + + + + + + + DataSet of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VELOCITY)}} + + + + + + + DataSet of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VISCOSITY)}} + + + + + + + DataSet of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VISCOSITY)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + DataSet of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + DataSet of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + DataSet of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + DataSet of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + DataSet of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::WATTAGE)}} + + + + + + + DataSet of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::WATTAGE)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + DataSet of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + DataSet of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DIAMETER)}} + + + + + + + DataSet of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DIAMETER)}} + + + + + + + DataSet of {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ORIENTATION)}} + + + + + + + DataSet of {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ORIENTATION)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + DataSet of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DECELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DECELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + DataSet of The force per unit area measured relative to a vacuum. + + + + + + + + + + + + + + DataSet of The force per unit area measured relative to a vacuum. + + + + + + + DataSet of The force per unit area measured relative to a vacuum. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of The force per unit area measured relative to a vacuum. + + + + + + + DataSet of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::OPENNESS)}} + + + + + + + DataSet of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::OPENNESS)}} + + + + + + + DataSet of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DEW_POINT)}} + + + + + + + DataSet of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DEW_POINT)}} + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + DataSet of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + DataSet of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + + + + + + DataSet of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + DataSet of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + DataSet of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + A cell of a table + + + + + + the key + + + + + + + + A cell of a table + + + + + + + {{term(key-value pair)}} published as part of a {{block(Table)}}. > + Note: In the {{term(XML)}} representation, {{block(TableEntry)}} + **MUST** appear as {{block(Entry)}}. + + + + + + + + + + + + + + {{term(key-value pair)}} published as part of a {{block(Table)}}. > + Note: In the {{term(XML)}} representation, {{block(TableEntry)}} + **MUST** appear as {{block(Entry)}}. + + + + + + + Table Entry of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + Cell of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + Table of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ACTIVE_AXES)}} + + + + + + + Table Entry of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + Cell of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + Table of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ACTUATOR_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + Cell of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + Table of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ASSET_CHANGED)}} + + + + + + + Table Entry of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + Cell of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + Table of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ASSET_REMOVED)}} + + + + + + + Table Entry of {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::AVAILABILITY)}} + + + + + + + Cell of {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::AVAILABILITY)}} + + + + + + + Table of {{def(EventEnum::AVAILABILITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::AVAILABILITY)}} + + + + + + + Table Entry of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + Cell of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + Table of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::AXIS_COUPLING)}} + + + + + + + Table Entry of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + Cell of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + Table of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::AXIS_FEEDRATE_OVERRIDE)}} + + + + + + + Table Entry of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + Cell of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + Table of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::AXIS_INTERLOCK)}} + + + + + + + Table Entry of {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::AXIS_STATE)}} + + + + + + + Cell of {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::AXIS_STATE)}} + + + + + + + Table of {{def(EventEnum::AXIS_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::AXIS_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::BLOCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::BLOCK)}} + + + + + + + Cell of {{def(EventEnum::BLOCK)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::BLOCK)}} + + + + + + + Table of {{def(EventEnum::BLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::BLOCK)}} + + + + + + + Table Entry of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + Cell of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + Table of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::BLOCK_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + Cell of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + Table of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CHUCK_INTERLOCK)}} + + + + + + + Table Entry of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + Cell of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + Table of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CHUCK_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::CODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CODE)}} + + + + + + + Cell of {{def(EventEnum::CODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CODE)}} + + + + + + + Table of {{def(EventEnum::CODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CODE)}} + + + + + + + Table Entry of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + Cell of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + Table of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::COMPOSITION_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + Cell of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + Table of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CONTROLLER_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + Cell of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + Table of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CONTROLLER_MODE_OVERRIDE)}} + + + + + + + Table Entry of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + Cell of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + Table of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::COUPLED_AXES)}} + + + + + + + Table Entry of {{def(EventEnum::DATE_CODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DATE_CODE)}} + + + + + + + Cell of {{def(EventEnum::DATE_CODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DATE_CODE)}} + + + + + + + Table of {{def(EventEnum::DATE_CODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DATE_CODE)}} + + + + + + + Table Entry of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + Cell of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + Table of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DEVICE_UUID)}} + + + + + + + Table Entry of {{def(EventEnum::DIRECTION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DIRECTION)}} + + + + + + + Cell of {{def(EventEnum::DIRECTION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DIRECTION)}} + + + + + + + Table of {{def(EventEnum::DIRECTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DIRECTION)}} + + + + + + + Table Entry of {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DOOR_STATE)}} + + + + + + + Cell of {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DOOR_STATE)}} + + + + + + + Table of {{def(EventEnum::DOOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DOOR_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + Cell of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + Table of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::EMERGENCY_STOP)}} + + + + + + + Table Entry of {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::END_OF_BAR)}} + + + + + + + Cell of {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::END_OF_BAR)}} + + + + + + + Table of {{def(EventEnum::END_OF_BAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::END_OF_BAR)}} + + + + + + + Table Entry of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + Cell of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + Table of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::EQUIPMENT_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::EXECUTION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::EXECUTION)}} + + + + + + + Cell of {{def(EventEnum::EXECUTION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::EXECUTION)}} + + + + + + + Table of {{def(EventEnum::EXECUTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::EXECUTION)}} + + + + + + + Table Entry of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + Cell of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + Table of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::FUNCTIONAL_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::HARDNESS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::HARDNESS)}} + + + + + + + Cell of {{def(EventEnum::HARDNESS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::HARDNESS)}} + + + + + + + Table of {{def(EventEnum::HARDNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::HARDNESS)}} + + + + + + + Table Entry of {{def(EventEnum::LINE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LINE)}} + + + + + + + Cell of {{def(EventEnum::LINE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LINE)}} + + + + + + + Table of {{def(EventEnum::LINE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LINE)}} + + + + + + + Table Entry of {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LINE_LABEL)}} + + + + + + + Cell of {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LINE_LABEL)}} + + + + + + + Table of {{def(EventEnum::LINE_LABEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LINE_LABEL)}} + + + + + + + Table Entry of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + Cell of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + Table of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LINE_NUMBER)}} + + + + + + + Table Entry of {{block(Resource)}} composed of material that is consumed + or used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{block(Resource)}} composed of material that is consumed + or used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + Cell of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + + + + + + + + Cell of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + Table of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{block(Resource)}} composed of material that is consumed or + used by the piece of equipment for production of parts, materials, or + other types of goods. + + + + + + + Table Entry of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + Cell of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + Table of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MATERIAL_LAYER)}} + + + + + + + Table Entry of {{def(EventEnum::MESSAGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MESSAGE)}} + + + + + + + Cell of {{def(EventEnum::MESSAGE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::MESSAGE)}} + + + + + + + Table of {{def(EventEnum::MESSAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MESSAGE)}} + + + + + + + Table Entry of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + Cell of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + Table of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::OPERATOR_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PALLET_ID)}} + + + + + + + Cell of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PALLET_ID)}} + + + + + + + Table of {{def(EventEnum::PALLET_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PALLET_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_COUNT)}} + + + + + + + Cell of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_COUNT)}} + + + + + + + Table of {{def(EventEnum::PART_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::PART_DETECT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_DETECT)}} + + + + + + + Cell of {{def(EventEnum::PART_DETECT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_DETECT)}} + + + + + + + Table of {{def(EventEnum::PART_DETECT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_DETECT)}} + + + + + + + Table Entry of {{def(EventEnum::PART_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_ID)}} + + + + + + + Cell of {{def(EventEnum::PART_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_ID)}} + + + + + + + Table of {{def(EventEnum::PART_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_NUMBER)}} + + + + + + + Cell of {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_NUMBER)}} + + + + + + + Table of {{def(EventEnum::PART_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_NUMBER)}} + + + + + + + Table Entry of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + Cell of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + Table of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PATH_FEEDRATE_OVERRIDE)}} + + + + + + + Table Entry of {{def(EventEnum::PATH_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PATH_MODE)}} + + + + + + + Cell of {{def(EventEnum::PATH_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PATH_MODE)}} + + + + + + + Table of {{def(EventEnum::PATH_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PATH_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::POWER_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::POWER_STATE)}} + + + + + + + Cell of {{def(EventEnum::POWER_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::POWER_STATE)}} + + + + + + + Table of {{def(EventEnum::POWER_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::POWER_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::POWER_STATUS)}} + + + + + + + Cell of {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::POWER_STATUS)}} + + + + + + + Table of {{def(EventEnum::POWER_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::POWER_STATUS)}} + + + + + + + Table Entry of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + Cell of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + Table of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROCESS_TIME)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM)}} + + + + + + + Table of {{def(EventEnum::PROGRAM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_COMMENT)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_EDIT)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_EDIT_NAME)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_HEADER)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_LOCATION)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + Cell of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + Table of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_LOCATION_TYPE)}} + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial + value is not defined, the nesting level associated with the highest or + initial nesting level of the program **MUST** default to zero (0). + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial + value is not defined, the nesting level associated with the highest or + initial nesting level of the program **MUST** default to zero (0). + + + + + + + Cell of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + Table of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROGRAM_NEST_LEVEL)}} If an initial value is + not defined, the nesting level associated with the highest or initial + nesting level of the program **MUST** default to zero (0). + + + + + + + Table Entry of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + Cell of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + Table of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ROTARY_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + Cell of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + + + + + + Cell of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + Table of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ROTARY_VELOCITY_OVERRIDE)}} This command + represents a percentage change to the velocity calculated by a logic or + motion program or set by a switch for a {{block(Rotary)}} type axis. + + + + + + + Table Entry of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + Cell of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + Table of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::SERIAL_NUMBER)}} + + + + + + + Table Entry of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + Cell of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + Table of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::SPINDLE_INTERLOCK)}} + + + + + + + Table Entry of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + Cell of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + Table of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_ASSET_ID)}} + + + + + + + Table Entry of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + Cell of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + Table of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_GROUP)}} + + + + + + + Table Entry of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_ID)}} + + + + + + + Cell of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_ID)}} + + + + + + + Table of {{def(EventEnum::TOOL_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_ID)}} + + + + + + + Table Entry of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + Cell of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + Table of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_NUMBER)}} + + + + + + + Table Entry of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + Cell of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + Table of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_OFFSET)}} + + + + + + + Table Entry of {{def(EventEnum::USER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::USER)}} + + + + + + + Cell of {{def(EventEnum::USER)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::USER)}} + + + + + + + Table of {{def(EventEnum::USER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::USER)}} + + + + + + + Table Entry of {{def(EventEnum::VARIABLE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::VARIABLE)}} + + + + + + + Cell of {{def(EventEnum::VARIABLE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::VARIABLE)}} + + + + + + + Table of {{def(EventEnum::VARIABLE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::VARIABLE)}} + + + + + + + Table Entry of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + Cell of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + + + + + + + + Cell of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + Table of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::WAIT_STATE)}} When + {{property(Execution::result)}} is not `WAIT`, + {{property(Observation::isUnavailable)}} of {{block(WaitState)}} + **MUST** be `true`. + + + + + + + Table Entry of leaf {{block(Component)}} composed of a string like piece + or filament of relatively rigid or flexible material provided in a + variety of diameters. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of leaf {{block(Component)}} composed of a string like piece + or filament of relatively rigid or flexible material provided in a + variety of diameters. + + + + + + + Cell of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + + + + + + + + Cell of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + Table of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of leaf {{block(Component)}} composed of a string like piece or + filament of relatively rigid or flexible material provided in a variety + of diameters. + + + + + + + Table Entry of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + Cell of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + Table of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::WORKHOLDING_ID)}} + + + + + + + Table Entry of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + Cell of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + Table of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::WORK_OFFSET)}} + + + + + + + Table Entry of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + Cell of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + Table of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::OPERATING_SYSTEM)}} + + + + + + + Table Entry of {{def(EventEnum::FIRMWARE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::FIRMWARE)}} + + + + + + + Cell of {{def(EventEnum::FIRMWARE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::FIRMWARE)}} + + + + + + + Table of {{def(EventEnum::FIRMWARE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::FIRMWARE)}} + + + + + + + Table Entry of {{def(EventEnum::APPLICATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::APPLICATION)}} + + + + + + + Cell of {{def(EventEnum::APPLICATION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::APPLICATION)}} + + + + + + + Table of {{def(EventEnum::APPLICATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::APPLICATION)}} + + + + + + + Table Entry of {{def(EventEnum::LIBRARY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LIBRARY)}} + + + + + + + Cell of {{def(EventEnum::LIBRARY)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LIBRARY)}} + + + + + + + Table of {{def(EventEnum::LIBRARY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LIBRARY)}} + + + + + + + Table Entry of {{def(EventEnum::HARDWARE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::HARDWARE)}} + + + + + + + Cell of {{def(EventEnum::HARDWARE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::HARDWARE)}} + + + + + + + Table of {{def(EventEnum::HARDWARE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::HARDWARE)}} + + + + + + + Table Entry of {{def(EventEnum::NETWORK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::NETWORK)}} + + + + + + + Cell of {{def(EventEnum::NETWORK)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::NETWORK)}} + + + + + + + Table of {{def(EventEnum::NETWORK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::NETWORK)}} + + + + + + + Table Entry of rotations about X, Y, and Z axes are expressed in A, B, + and C respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of rotations about X, Y, and Z axes are expressed in A, B, + and C respectively within a 3-dimensional vector. + + + + + + + Cell of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + + + + + + Cell of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + Table of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of rotations about X, Y, and Z axes are expressed in A, B, and C + respectively within a 3-dimensional vector. + + + + + + + Table Entry of translations along X, Y, and Z axes are expressed as x,y, + and z respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of translations along X, Y, and Z axes are expressed as x,y, + and z respectively within a 3-dimensional vector. + + + + + + + Cell of translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + + + + + + + + Cell of translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + Table of translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of translations along X, Y, and Z axes are expressed as x,y, and z + respectively within a 3-dimensional vector. + + + + + + + Table Entry of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + Cell of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + Table of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROCESS_KIND_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_STATUS)}} If unique identifier is + given, part status is for that individual. If group identifier is given + without a unique identifier, then the status is assumed to be for the + whole group. + + + + + + + Cell of {{def(EventEnum::PART_STATUS)}} If unique identifier is given, + part status is for that individual. If group identifier is given without + a unique identifier, then the status is assumed to be for the whole + group. + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_STATUS)}} If unique identifier is given, + part status is for that individual. If group identifier is given without + a unique identifier, then the status is assumed to be for the whole + group. + + + + + + + Table of {{def(EventEnum::PART_STATUS)}} If unique identifier is given, + part status is for that individual. If group identifier is given without + a unique identifier, then the status is assumed to be for the whole + group. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_STATUS)}} If unique identifier is given, + part status is for that individual. If group identifier is given without + a unique identifier, then the status is assumed to be for the whole + group. + + + + + + + Table Entry of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + Cell of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + Table of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ALARM_LIMIT)}} + + + + + + + Table Entry of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + Cell of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + Table of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROCESS_AGGREGATE_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Cell of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_KIND_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table Entry of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + Cell of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + Table of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ADAPTER_URI)}} + + + + + + + Table Entry of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + Cell of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + Table of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DEVICE_REMOVED)}} + + + + + + + Table Entry of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + Cell of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + Table of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DEVICE_CHANGED)}} + + + + + + + Table Entry of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + Cell of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + Table of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::SPECIFICATION_LIMIT)}} + + + + + + + Table Entry of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + Cell of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + Table of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CONNECTION_STATUS)}} + + + + + + + Table Entry of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + Cell of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + Table of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ADAPTER_SOFTWARE_VERSION)}} + + + + + + + Table Entry of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + Cell of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + Table of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::SENSOR_ATTACHMENT)}} + + + + + + + Table Entry of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + Cell of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + Table of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CONTROL_LIMIT)}} + + + + + + + Table Entry of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + Cell of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + Table of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DEVICE_ADDED)}} + + + + + + + Table Entry of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + Cell of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + Table of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MTCONNECT_VERSION)}} + + + + + + + Table Entry of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + Cell of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + Table of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROCESS_OCCURRENCE_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Cell of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_GROUP_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table Entry of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Cell of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_UNIQUE_ID)}} If no + {{property(DataItem::subType)}} is specified, `UUID` is default. + + + + + + + Table Entry of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + Cell of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + Table of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ACTIVATION_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + Cell of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + Table of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::DEACTIVATION_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + Cell of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + Table of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TRANSFER_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + Cell of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + Table of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LOAD_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + Cell of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + Table of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_PROCESSING_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + Cell of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + Table of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PROCESS_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::VALVE_STATE)}} + + + + + + + Cell of {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::VALVE_STATE)}} + + + + + + + Table of {{def(EventEnum::VALVE_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::VALVE_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LOCK_STATE)}} + + + + + + + Cell of {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LOCK_STATE)}} + + + + + + + Table of {{def(EventEnum::LOCK_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LOCK_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + Cell of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + Table of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::UNLOAD_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + Cell of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + Table of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CYCLE_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + Cell of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + Table of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::OPERATING_MODE)}} + + + + + + + Table Entry of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + Cell of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + Table of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ASSET_COUNT)}} + + + + + + + Table Entry of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + Cell of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + + + + + + Cell of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + Table of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MAINTENANCE_LIST)}} If + {{property(MaintenanceList::result::Interval)}} `key` is not provided, + it is assumed `ABSOLUTE`. If + {{property(MaintenanceList::result::Direction)}} `key` is not provided, + it is assumed `UP`. If {{property(MaintenanceList::result::Units)}} + `key` is not provided, it is assumed to be `COUNT`. + + + + + + + Table Entry of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + Cell of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + Table of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::FIXTURE_ID)}} + + + + + + + Table Entry of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + Cell of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + Table of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::PART_COUNT_TYPE)}} + + + + + + + Table Entry of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + Cell of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + Table of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CLOCK_TIME)}} + + + + + + + Table Entry of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + Cell of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + Table of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::NETWORK_PORT)}} + + + + + + + Table Entry of {{def(EventEnum::HOST_NAME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::HOST_NAME)}} + + + + + + + Cell of {{def(EventEnum::HOST_NAME)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::HOST_NAME)}} + + + + + + + Table of {{def(EventEnum::HOST_NAME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::HOST_NAME)}} + + + + + + + Table Entry of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + Cell of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + Table of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LEAK_DETECT)}} + + + + + + + Table Entry of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + Cell of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + Table of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::BATTERY_STATE)}} + + + + + + + Table Entry of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + Cell of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + Table of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::FEATURE_PERSISTENT_ID)}} + + + + + + + Table Entry of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + Cell of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + Table of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::SENSOR_STATE)}} + + + + + + + Table Entry of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + Cell of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + + + + + + + + Cell of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + Table of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of tabular {{def(EventEnum::COMPONENT_DATA)}} If the + {{block(Component)}} multiplicity can be determined, the device model + **MUST** use a fixed set of {{block(Component)}}s. + {{block(ComponentData)}} **MUST** provide a {{block(DataItem)}} + {{block(Definition)}}. + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + Cell of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + + + + + + Cell of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + Table of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of tabular representation of {{def(EventEnum::WORK_OFFSETS)}} + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + Cell of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + + + + + + Cell of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + Table of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of tabular representation of {{def(EventEnum::TOOL_OFFSETS)}} + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + Cell of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + + + + + + + + Cell of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + Table of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of tabular representation of + {{def(EventEnum::FEATURE_MEASUREMENT)}} {{block(FeatureMeasurement)}} + **MAY** include a {{term(characteristic)}} in which case it **MAY** + include a `CHARACTERISTIC_STATUS`. + + + + + + + Table Entry of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + Cell of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + Table of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CHARACTERISTIC_PERSISTENT_ID)}} + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + Table of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MEASUREMENT_TYPE)}} Examples: `POINT`, + `RADIUS`, `ANGLE`, `LENGTH`, etc. + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + Table of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MEASUREMENT_VALUE)}} + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + Table of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::MEASUREMENT_UNITS)}} + + + + + + + Table Entry of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + Cell of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + Table of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::CHARACTERISTIC_STATUS)}} + + + + + + + Table Entry of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + Cell of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + Table of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::UNCERTAINTY_TYPE)}} + + + + + + + Table Entry of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + Cell of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + Table of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::UNCERTAINTY)}} + + + + + + + Table Entry of See {{sect(AlarmLimits)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of See {{sect(AlarmLimits)}}. + + + + + + + Cell of See {{sect(AlarmLimits)}}. + + + + + + + + + + + + + + Cell of See {{sect(AlarmLimits)}}. + + + + + + + Table of See {{sect(AlarmLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of See {{sect(AlarmLimits)}}. + + + + + + + Table Entry of See {{sect(ControlLimits)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of See {{sect(ControlLimits)}}. + + + + + + + Cell of See {{sect(ControlLimits)}}. + + + + + + + + + + + + + + Cell of See {{sect(ControlLimits)}}. + + + + + + + Table of See {{sect(ControlLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of See {{sect(ControlLimits)}}. + + + + + + + Table Entry of See {{sect(SpecificationLimits)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of See {{sect(SpecificationLimits)}}. + + + + + + + Cell of See {{sect(SpecificationLimits)}}. + + + + + + + + + + + + + + Cell of See {{sect(SpecificationLimits)}}. + + + + + + + Table of See {{sect(SpecificationLimits)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of See {{sect(SpecificationLimits)}}. + + + + + + + Table Entry of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + Cell of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + Table of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::TOOL_CUTTING_ITEM)}} + + + + + + + Table Entry of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + Cell of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + Table of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LOCATION_ADDRESS)}} + + + + + + + Table Entry of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + Cell of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + Table of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::ACTIVE_POWER_SOURCE)}} + + + + + + + Table Entry of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + Cell of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + Table of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LOCATION_NARRATIVE)}} + + + + + + + Table Entry of {{def(EventEnum::THICKNESS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::THICKNESS)}} + + + + + + + Cell of {{def(EventEnum::THICKNESS)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::THICKNESS)}} + + + + + + + Table of {{def(EventEnum::THICKNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::THICKNESS)}} + + + + + + + Table Entry of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + Cell of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + + + + + + Cell of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + Table of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(EventEnum::LOCATION_SPATIAL_GEOGRAPHIC)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_FEED)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_CHANGE)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_RETRACT)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_LOAD)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::MATERIAL_UNLOAD)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + Cell of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + Table of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::OPEN_CHUCK)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + Cell of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + Table of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::OPEN_DOOR)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + Cell of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + Table of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::PART_CHANGE)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + Cell of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + Table of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::CLOSE_DOOR)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + Cell of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + Table of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::CLOSE_CHUCK)}} + + + + + + + Table Entry of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + Cell of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + + + + + + Cell of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + Table of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(InterfaceEventEnum::INTERFACE_STATE)}} When the + {{block(InterfaceState)}} is `DISABLED`, the state of all data items + that are specific for the {{term(interaction model)}} associated with + that {{block(Interface)}} **MUST** be set to `NOT_READY`. + + + + + + + Table Entry of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ACCELERATION)}} + + + + + + + Cell of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ACCELERATION)}} + + + + + + + Table of {{def(SampleEnum::ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ACCELERATION)}} + + + + + + + Table Entry of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + Cell of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + Table of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ACCUMULATED_TIME)}} + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE)}} + + + + + + + Cell of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::AMPERAGE)}} + + + + + + + Table of {{def(SampleEnum::AMPERAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::AMPERAGE)}} + + + + + + + Table Entry of {{def(SampleEnum::ANGLE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ANGLE)}} + + + + + + + Cell of {{def(SampleEnum::ANGLE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ANGLE)}} + + + + + + + Table of {{def(SampleEnum::ANGLE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ANGLE)}} + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + Cell of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + Table of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ANGULAR_ACCELERATION)}} + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + Cell of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + Table of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ANGULAR_VELOCITY)}} + + + + + + + Table Entry of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + Cell of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + Table of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::AXIS_FEEDRATE)}} + + + + + + + Table Entry of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + Cell of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + Table of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CAPACITY_FLUID)}} + + + + + + + Table Entry of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + Cell of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + Table of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CAPACITY_SPATIAL)}} + + + + + + + Table Entry of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + Cell of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + Table of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CONCENTRATION)}} + + + + + + + Table Entry of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + Cell of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + Table of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CONDUCTIVITY)}} + + + + + + + Table Entry of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + Cell of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + Table of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CUTTING_SPEED)}} + + + + + + + Table Entry of {{def(SampleEnum::DENSITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DENSITY)}} + + + + + + + Cell of {{def(SampleEnum::DENSITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DENSITY)}} + + + + + + + Table of {{def(SampleEnum::DENSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DENSITY)}} + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + Table of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEPOSITION_ACCELERATION_VOLUMETRIC)}} + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + Table of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEPOSITION_DENSITY)}} + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + Table of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEPOSITION_MASS)}} + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + Table of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEPOSITION_RATE_VOLUMETRIC)}} + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + Table of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEPOSITION_VOLUME)}} + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT)}} + + + + + + + Table Entry of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + Cell of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + Table of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ELECTRICAL_ENERGY)}} + + + + + + + Table Entry of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + Cell of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + Table of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::EQUIPMENT_TIMER)}} + + + + + + + Table Entry of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + Cell of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + Table of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FILL_LEVEL)}} + + + + + + + Table Entry of {{def(SampleEnum::FLOW)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FLOW)}} + + + + + + + Cell of {{def(SampleEnum::FLOW)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FLOW)}} + + + + + + + Table of {{def(SampleEnum::FLOW)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FLOW)}} + + + + + + + Table Entry of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FREQUENCY)}} + + + + + + + Cell of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FREQUENCY)}} + + + + + + + Table of {{def(SampleEnum::FREQUENCY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FREQUENCY)}} + + + + + + + Table Entry of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + Cell of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + Table of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::GLOBAL_POSITION)}} + + + + + + + Table Entry of {{def(SampleEnum::LENGTH)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::LENGTH)}} + + + + + + + Cell of {{def(SampleEnum::LENGTH)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::LENGTH)}} + + + + + + + Table of {{def(SampleEnum::LENGTH)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::LENGTH)}} + + + + + + + Table Entry of {{def(SampleEnum::LEVEL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::LEVEL)}} + + + + + + + Cell of {{def(SampleEnum::LEVEL)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::LEVEL)}} + + + + + + + Table of {{def(SampleEnum::LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::LEVEL)}} + + + + + + + Table Entry of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + Cell of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + Table of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::LINEAR_FORCE)}} + + + + + + + Table Entry of {{def(SampleEnum::LOAD)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::LOAD)}} + + + + + + + Cell of {{def(SampleEnum::LOAD)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::LOAD)}} + + + + + + + Table of {{def(SampleEnum::LOAD)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::LOAD)}} + + + + + + + Table Entry of {{def(SampleEnum::MASS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::MASS)}} + + + + + + + Cell of {{def(SampleEnum::MASS)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::MASS)}} + + + + + + + Table of {{def(SampleEnum::MASS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::MASS)}} + + + + + + + Table Entry of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + Cell of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + Table of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::PATH_FEEDRATE)}} + + + + + + + Table Entry of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Cell of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Table of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::PATH_FEEDRATE_PER_REVOLUTION)}} + + + + + + + Table Entry of Example + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of Example + + + + + + + Cell of Example + + + + + + + + + + + + + + Cell of Example + + + + + + + Table of Example + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of Example + + + + + + + Table Entry of {{def(SampleEnum::PH)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::PH)}} + + + + + + + Cell of {{def(SampleEnum::PH)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::PH)}} + + + + + + + Table of {{def(SampleEnum::PH)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::PH)}} + + + + + + + Table Entry of {{def(SampleEnum::POSITION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::POSITION)}} + + + + + + + Cell of {{def(SampleEnum::POSITION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::POSITION)}} + + + + + + + Table of {{def(SampleEnum::POSITION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::POSITION)}} + + + + + + + Table Entry of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Cell of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Table of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::POWER_FACTOR)}} + + + + + + + Table Entry of Description + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of Description + + + + + + + Cell of Description + + + + + + + + + + + + + + Cell of Description + + + + + + + Table of Description + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of Description + + + + + + + Table Entry of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + Cell of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + Table of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::PROCESS_TIMER)}} + + + + + + + Table Entry of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::RESISTANCE)}} + + + + + + + Cell of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::RESISTANCE)}} + + + + + + + Table of {{def(SampleEnum::RESISTANCE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::RESISTANCE)}} + + + + + + + Table Entry of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + Cell of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + Table of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ROTARY_VELOCITY)}} + + + + + + + Table Entry of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + Cell of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + Table of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::SOUND_LEVEL)}} + + + + + + + Table Entry of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + Cell of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + Table of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::SPINDLE_SPEED)}} + + + + + + + Table Entry of {{def(SampleEnum::STRAIN)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::STRAIN)}} + + + + + + + Cell of {{def(SampleEnum::STRAIN)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::STRAIN)}} + + + + + + + Table of {{def(SampleEnum::STRAIN)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::STRAIN)}} + + + + + + + Table Entry of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + Cell of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + Table of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::TEMPERATURE)}} + + + + + + + Table Entry of {{def(SampleEnum::TENSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::TENSION)}} + + + + + + + Cell of {{def(SampleEnum::TENSION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::TENSION)}} + + + + + + + Table of {{def(SampleEnum::TENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::TENSION)}} + + + + + + + Table Entry of {{def(SampleEnum::TILT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::TILT)}} + + + + + + + Cell of {{def(SampleEnum::TILT)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::TILT)}} + + + + + + + Table of {{def(SampleEnum::TILT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::TILT)}} + + + + + + + Table Entry of {{def(SampleEnum::TORQUE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::TORQUE)}} + + + + + + + Cell of {{def(SampleEnum::TORQUE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::TORQUE)}} + + + + + + + Table of {{def(SampleEnum::TORQUE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::TORQUE)}} + + + + + + + Table Entry of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VELOCITY)}} + + + + + + + Cell of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VELOCITY)}} + + + + + + + Table of {{def(SampleEnum::VELOCITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VELOCITY)}} + + + + + + + Table Entry of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VISCOSITY)}} + + + + + + + Cell of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VISCOSITY)}} + + + + + + + Table of {{def(SampleEnum::VISCOSITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VISCOSITY)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE)}} + + + + + + + Cell of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLTAGE)}} + + + + + + + Table of {{def(SampleEnum::VOLTAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLTAGE)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + Cell of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + Table of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLT_AMPERE)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + Cell of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + Table of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLT_AMPERE_REACTIVE)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + Cell of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + Table of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLUME_FLUID)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + Cell of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + Table of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLUME_SPATIAL)}} + + + + + + + Table Entry of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::WATTAGE)}} + + + + + + + Cell of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::WATTAGE)}} + + + + + + + Table of {{def(SampleEnum::WATTAGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::WATTAGE)}} + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + Cell of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + Table of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::AMPERAGE_DC)}} + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + Cell of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + Table of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::AMPERAGE_AC)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + Cell of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + Table of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLTAGE_AC)}} + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + Cell of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + Table of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::VOLTAGE_DC)}} + + + + + + + Table Entry of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + Cell of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + Table of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::X_DIMENSION)}} + + + + + + + Table Entry of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + Cell of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + Table of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::Y_DIMENSION)}} + + + + + + + Table Entry of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + Cell of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + Table of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::Z_DIMENSION)}} + + + + + + + Table Entry of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DIAMETER)}} + + + + + + + Cell of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DIAMETER)}} + + + + + + + Table of {{def(SampleEnum::DIAMETER)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DIAMETER)}} + + + + + + + Table Entry of {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ORIENTATION)}} + + + + + + + Cell of {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ORIENTATION)}} + + + + + + + Table of {{def(SampleEnum::ORIENTATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ORIENTATION)}} + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + Table of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::HUMIDITY_RELATIVE)}} + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + Table of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::HUMIDITY_ABSOLUTE)}} + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + Table of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::HUMIDITY_SPECIFIC)}} + + + + + + + Table Entry of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + Cell of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + Table of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::PRESSURIZATION_RATE)}} + + + + + + + Table Entry of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DECELERATION)}} + + + + + + + Cell of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DECELERATION)}} + + + + + + + Table of {{def(SampleEnum::DECELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DECELERATION)}} + + + + + + + Table Entry of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + Cell of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + Table of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ASSET_UPDATE_RATE)}} + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + Cell of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + Table of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::ANGULAR_DECELERATION)}} + + + + + + + Table Entry of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + Cell of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + Table of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::OBSERVATION_UPDATE_RATE)}} + + + + + + + Table Entry of The force per unit area measured relative to a vacuum. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of The force per unit area measured relative to a vacuum. + + + + + + + Cell of The force per unit area measured relative to a vacuum. + + + + + + + + + + + + + + Cell of The force per unit area measured relative to a vacuum. + + + + + + + Table of The force per unit area measured relative to a vacuum. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of The force per unit area measured relative to a vacuum. + + + + + + + Table Entry of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::OPENNESS)}} + + + + + + + Cell of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::OPENNESS)}} + + + + + + + Table of {{def(SampleEnum::OPENNESS)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::OPENNESS)}} + + + + + + + Table Entry of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DEW_POINT)}} + + + + + + + Cell of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DEW_POINT)}} + + + + + + + Table of {{def(SampleEnum::DEW_POINT)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DEW_POINT)}} + + + + + + + Table Entry of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + Cell of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + + + + + + + + Cell of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: $$Mass\times + GravitationalAcceleration$$ + + + + + + + Table of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::GRAVITATIONAL_FORCE)}} > Note: + $$Mass\times GravitationalAcceleration$$ + + + + + + + Table Entry of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + Cell of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + Table of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::GRAVITATIONAL_ACCELERATION)}} + + + + + + + Table Entry of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + Cell of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + Table of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::BATTERY_CAPACITY)}} + + + + + + + Table Entry of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + Cell of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + Table of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DISCHARGE_RATE)}} + + + + + + + Table Entry of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + Cell of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + Table of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::CHARGE_RATE)}} + + + + + + + Table Entry of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + Cell of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + Table of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::BATTERY_CHARGE)}} + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR)}} + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR_LINEAR)}} + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::SETTLING_ERROR_ANGULAR)}} + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR)}} + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR_ANGULAR)}} + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::FOLLOWING_ERROR_LINEAR)}} + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT_LINEAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + + + + + + Cell of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::DISPLACEMENT_ANGULAR)}} > Note: The + displacement vector **MAY** be defined by the motion of the owning + {{block(Component)}}. + + + + + + + Table Entry of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + Constraints for Cell Values + + + + + + + + + + + Table Entry of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + Cell of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + + + + + + Cell of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + Table of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + + + Constraints for Entry Values + + + + + + + + The number of entries + + + + + + + + + + Table of {{def(SampleEnum::POSITION_CARTESIAN)}} + + + + + + + The description of the Condition + + + + + + + + The device's severity + + + + + + + + Identifier of an individual condition activation provided by a piece of + equipment + + + + + + + + A qualifier for the condition + + + + + + + The value is too high + + + + + + + The value is too low + + + + + + + + + Description + + + + + + + + + type of the power source. + + + + + + + The component specific Notifcation code + + + + + + + The component specific Notifcation code + + + + + + + An optional attribute that helps qualify the condition + + + + + + + The statistical operation on this data + + + + + + + + + + Description + + + + + + + Condition that has transitioned from Normal to either Warning or Fault + + + + + + + + Identifier of an individual condition activation provided by a + piece of equipment + + + + + + + + + + Condition that has transitioned from Normal to either Warning or Fault + + + + + + + The conditon can not be determined. + + + + + + + + + + The conditon can not be determined. + + + + + + + {{term(condition state)}} that indicates operation within specified + limits. + + + + + + + + + + {{term(condition state)}} that indicates operation within specified + limits. + + + + + + + {{term(condition state)}} that requires concern and supervision and may + become hazardous if no action is taken. + + + + + + + + + + {{term(condition state)}} that requires concern and supervision and may + become hazardous if no action is taken. + + + + + + + {{term(condition state)}} that requires intervention to continue + operation to function properly. + + + + + + + + + + {{term(condition state)}} that requires intervention to continue + operation to function properly. + + + + + + + DEPRECATED: An Notifcation code as defined by the component + + + + + + + + DEPRECATED: Types of Notifcations + + + + + + + A failure + + + + + + + A fault occurred + + + + + + + A spindle crash + + + + + + + A component has jammed + + + + + + + The component has been overloaded + + + + + + + E-Stop was pushed + + + + + + + A material failure has occurred + + + + + + + An operators message. Used with INFO severity + + + + + + + Another Notifcation type + + + + + + + + + DEPRECATED: The active or cleared state of the notification + + + + + + + The notification is active + + + + + + + The notification has been cleared + + + + + + + + + level of severity on a scale of 1-10. + + + + + + + The notification is critical + + + + + + + An error has occurred + + + + + + + A medium level notification that should be observed + + + + + + + This notification is for information purposes only + + + + + + + + + {{def(EventEnum::ALARM)}} + + + + + + + + {{def(EventEnum::CODE)}} + + + + + + + level of severity on a scale of 1-10. + + + + + + + The state + + + + + + + The component specific Notifcation code + + + + + + + + + + {{def(EventEnum::ALARM)}} + + + + + + + The possible values for an interface event + + + + + + + The value is unavailable + + + + + + + The interface is not ready + + + + + + + The interface is ready + + + + + + + The interface is actively executing + + + + + + + The interface has completed the action + + + + + + + The interface action has failed + + + + + + + + + An abstract interface event + + + + + + + + + + + + + + An abstract interface event + + + + + + + The state of the interface + + + + + + + The value is unavailable + + + + + + + The interface is enabled + + + + + + + The interface is disabled + + + + + + \ No newline at end of file diff --git a/schemas/readme.md b/schemas/readme.md index a5c9052b3..b934c924f 100644 --- a/schemas/readme.md +++ b/schemas/readme.md @@ -1,4 +1,4 @@ -MTConnect Schema Files Versions 1.0 - 2.3 +MTConnect Schema Files Versions 1.0 - 2.5 === Files are named with respect to the section of the standard they apply. @@ -20,6 +20,8 @@ The files included in this directory are as follows: * Version 2.1 (With XSD 1.0 compatible files) * Version 2.2 (With XSD 1.0 compatible files) * Version 2.3 (With XSD 1.0 compatible files) +* Version 2.4 (With XSD 1.0 compatible files) +* Version 2.5 (With XSD 1.0 compatible files) The schemas are replicated to http://schemas.mtconnect.org