diff --git a/src/mtconnect/pipeline/validator.hpp b/src/mtconnect/pipeline/validator.hpp index 44c02bec..352cc30f 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/observation_validations.hpp b/src/mtconnect/validation/observation_validations.hpp index bc2843f2..0fbb4b07 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", {}}, diff --git a/src/mtconnect/validation/observations.hpp b/src/mtconnect/validation/observations.hpp index c5a843ed..c6df2c85 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 4b8da845..1fe9c7fa 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")); +} +