diff --git a/src/OMSimulatorLib/Model.cpp b/src/OMSimulatorLib/Model.cpp index 4d0070913..fdd3073e1 100644 --- a/src/OMSimulatorLib/Model.cpp +++ b/src/OMSimulatorLib/Model.cpp @@ -353,13 +353,6 @@ oms_status_enu_t oms::Model::list(const oms::ComRef& cref, char** contents) oms_status_enu_t oms::Model::exportSnapshot(const oms::ComRef& cref, char** contents) { - // only top level model is allowed - if (!cref.isEmpty()) - { - //return logError("only top level model is allowed, unknown model: " + std::string(cref)); - return logError("\"" + std::string(getCref()+std::string(cref)) + "\" is not a top level model"); - } - Snapshot snapshot; pugi::xml_node oms_ssd = snapshot.newResourceNode("SystemStructure.ssd"); @@ -378,9 +371,13 @@ oms_status_enu_t oms::Model::exportSnapshot(const oms::ComRef& cref, char** cont // TODO ssm file } - snapshot.writeDocument(contents); + if (cref.isEmpty()) + return snapshot.writeDocument(contents); - return oms_status_ok; + // query for partial snapshot + Snapshot partialSnapshot(true); + snapshot.exportPartialSnapshot(cref, partialSnapshot); + return partialSnapshot.writeDocument(contents); } oms_status_enu_t oms::Model::exportSSVTemplate(const oms::ComRef& cref, const std::string& filename) diff --git a/src/OMSimulatorLib/OMSimulator.cpp b/src/OMSimulatorLib/OMSimulator.cpp index a5d3b374d..0c459e866 100644 --- a/src/OMSimulatorLib/OMSimulator.cpp +++ b/src/OMSimulatorLib/OMSimulator.cpp @@ -219,10 +219,16 @@ oms_status_enu_t oms_exportSnapshot(const char* cref_, char** contents) { oms::ComRef tail(cref_); oms::ComRef front = tail.pop_front(); - oms::Model* model = oms::Scope::GetInstance().getModel(front); + + oms::ComRef modelCref(front); + modelCref.pop_suffix(); + + oms::Model* model = oms::Scope::GetInstance().getModel(modelCref); if (!model) return logError_ModelNotInScope(front); + if (tail.isEmpty() && front.hasSuffix()) + return model->exportSnapshot(oms::ComRef(":" + front.suffix()), contents); return model->exportSnapshot(tail, contents); } diff --git a/src/OMSimulatorLib/Snapshot.cpp b/src/OMSimulatorLib/Snapshot.cpp index 3dc3edfd6..c203cab10 100644 --- a/src/OMSimulatorLib/Snapshot.cpp +++ b/src/OMSimulatorLib/Snapshot.cpp @@ -35,10 +35,12 @@ #include -oms::Snapshot::Snapshot() +oms::Snapshot::Snapshot(bool partial) { // set the document with the root node doc.append_child(oms::ssp::Version1_0::snap_shot); + pugi::xml_node oms_snapshot = doc.document_element(); + oms_snapshot.append_attribute("partial") = partial ? "true" : "false"; } oms::Snapshot::~Snapshot() @@ -102,6 +104,17 @@ oms_status_enu_t oms::Snapshot::importResourceNode(const filesystem::path& filen return oms_status_ok; } +oms_status_enu_t oms::Snapshot::importPartialResourceNode(const filesystem::path& filename, const filesystem::path& nodename, const pugi::xml_node& node) +{ + pugi::xml_node oms_snapshot = doc.document_element(); + pugi::xml_node oms_file = oms_snapshot.append_child(oms::ssp::Version1_0::oms_file); + oms_file.append_attribute("name") = filename.generic_string().c_str(); + oms_file.append_attribute("node") = nodename.generic_string().c_str(); + oms_file.append_copy(node); + + return oms_status_ok; +} + void oms::Snapshot::getResources(std::vector& resources) const { pugi::xml_node oms_snapshot = doc.document_element(); @@ -173,6 +186,67 @@ pugi::xml_node oms::Snapshot::getTemplateResourceNodeSSV(const filesystem::path& return node_parameters; } +oms_status_enu_t oms::Snapshot::exportPartialSnapshot(const ComRef& cref, Snapshot& partialSnapshot) +{ + ComRef subCref(cref); + std::string suffix = subCref.pop_suffix(); + + // copy only single file + if (!suffix.empty() && subCref.isEmpty()) + { + pugi::xml_node node = getResourceNode(filesystem::path(suffix)); + if (!node) + return logError("Failed to find node \"" + suffix + "\""); + + partialSnapshot.importResourceNode(filesystem::path(suffix), node); + } + + // check cref if to filter component: subCref + if (!subCref.isEmpty() && !suffix.empty()) + { + ComRef tail(subCref); + ComRef front = tail.pop_front(); + + // get SystemStructure.ssd + pugi::xml_node ssdNode = getResourceNode("SystemStructure.ssd"); + pugi::xml_node systemNode = ssdNode.first_child(); + + std::string nodeName = (ComRef(ssdNode.attribute("name").as_string()) + subCref); + + if (tail.isEmpty()) + { + // return system + if (systemNode.attribute("name").as_string() == std::string(front)) + { + partialSnapshot.importPartialResourceNode("SystemStructure.ssd", nodeName, systemNode); + } + } + else + { + // iterate System + for (pugi::xml_node_iterator it = systemNode.begin(); it != systemNode.end(); ++it) + { + if (std::string(it->name()) == oms::ssp::Draft20180219::ssd::elements) + { + for (pugi::xml_node_iterator itElements = (*it).begin(); itElements != (*it).end(); ++itElements) + { + std::string name = itElements->name(); + if (name == oms::ssp::Draft20180219::ssd::system || name == oms::ssp::Draft20180219::ssd::component) + { + if(itElements->attribute("name").as_string() == std::string(tail)) + { + partialSnapshot.importPartialResourceNode("SystemStructure.ssd", nodeName, *itElements); + } + } + } + } + } + } + } + + return oms_status_ok; +} + oms_status_enu_t oms::Snapshot::writeDocument(char** contents) { class : public pugi::xml_writer diff --git a/src/OMSimulatorLib/Snapshot.h b/src/OMSimulatorLib/Snapshot.h index 7f1aed5b7..aaa6cd2c6 100644 --- a/src/OMSimulatorLib/Snapshot.h +++ b/src/OMSimulatorLib/Snapshot.h @@ -32,9 +32,10 @@ #ifndef _OMS_SNAPSHOT_H_ #define _OMS_SNAPSHOT_H_ +#include "ComRef.h" #include "OMSFileSystem.h" -#include "Types.h" #include "ssd/Tags.h" +#include "Types.h" #include #include @@ -45,7 +46,7 @@ namespace oms class Snapshot { public: - Snapshot(); + Snapshot(bool partial=false); ~Snapshot(); oms_status_enu_t import(const char* snapshot); @@ -61,12 +62,16 @@ namespace oms pugi::xml_node getTemplateResourceNodeSSD(const filesystem::path& filename); pugi::xml_node getTemplateResourceNodeSSV(const filesystem::path& filename); + oms_status_enu_t exportPartialSnapshot(const ComRef& cref, Snapshot& partialSnapshot); void debugPrintNode(const filesystem::path& filename) const; void debugPrintAll() const; oms_status_enu_t writeDocument(char** contents); + private: + oms_status_enu_t importPartialResourceNode(const filesystem::path& filename, const filesystem::path& nodename, const pugi::xml_node& node); + private: // stop the compiler generating methods copying the object Snapshot(Snapshot const& copy); ///< not implemented diff --git a/testsuite/OMSimulator/Makefile b/testsuite/OMSimulator/Makefile index b8814f5af..f96a211b9 100644 --- a/testsuite/OMSimulator/Makefile +++ b/testsuite/OMSimulator/Makefile @@ -20,6 +20,7 @@ import_parameter_mapping_from_ssm.lua \ import_parameter_mapping_inline.lua \ importStartValues.lua \ multipleConnections.lua \ +partialSnapshot.lua \ PI_Controller.lua \ QuarterCarModel.DisplacementDisplacement.lua \ rename.lua \ diff --git a/testsuite/OMSimulator/importStartValues.lua b/testsuite/OMSimulator/importStartValues.lua index e2707ab00..9158f1cb6 100644 --- a/testsuite/OMSimulator/importStartValues.lua +++ b/testsuite/OMSimulator/importStartValues.lua @@ -33,7 +33,7 @@ oms_delete("importStartValues") -- warning: Wrong/deprecated content detected but successfully loaded. Please re-export the SSP file to avoid this message. -- warning: Wrong/deprecated content detected but successfully loaded. Please re-export the SSP file to avoid this message. -- --- +-- -- -- -- diff --git a/testsuite/OMSimulator/import_export_snapshot.lua b/testsuite/OMSimulator/import_export_snapshot.lua index b1cda5e65..7eb97b663 100644 --- a/testsuite/OMSimulator/import_export_snapshot.lua +++ b/testsuite/OMSimulator/import_export_snapshot.lua @@ -1,112 +1,44 @@ -- status: correct --- teardown_command: rm -rf import_export_snapshot_lua/ +-- teardown_command: rm -rf import_export_snapshot_lua/ import_export_snapshot.ssp -- linux: yes -- mingw: yes -- win: no -- mac: no - oms_setCommandLineOption("--suppressPath=true --exportParametersInline=false") status = oms_setTempDirectory("./import_export_snapshot_lua/") oms_newModel("import_export_snapshot") oms_addSystem("import_export_snapshot.root", oms_system_wc) + oms_addConnector("import_export_snapshot.root.C1", oms_causality_input, oms_signal_type_real) oms_setReal("import_export_snapshot.root.C1", -10) oms_addSubModel("import_export_snapshot.root.add", "../resources/Modelica.Blocks.Math.Add.fmu") - oms_setReal("import_export_snapshot.root.add.u1", 10) oms_setReal("import_export_snapshot.root.add.k1", 30) --- src1 = oms_list("import_export_snapshot") --- print(src1) - oms_export("import_export_snapshot", "import_export_snapshot.ssp"); oms_delete("import_export_snapshot") oms_importFile("import_export_snapshot.ssp"); -src1 = oms_list("import_export_snapshot") -print(src1) - src2 = oms_exportSnapshot("import_export_snapshot") print(src2) oms_importSnapshot("import_export_snapshot", src2) --- check of error msg -oms_exportSnapshot("import_export_snapshot.root.add") - oms_setStopTime("import_export_snapshot", 2) oms_instantiate("import_export_snapshot") - oms_initialize("import_export_snapshot") oms_simulate("import_export_snapshot") oms_terminate("import_export_snapshot") oms_delete("import_export_snapshot") - -- Result: -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- +-- -- -- -- @@ -180,8 +112,5 @@ oms_delete("import_export_snapshot") -- -- -- --- error: [exportSnapshot] "import_export_snapshot.root.add" is not a top level model -- info: Result file: import_export_snapshot_res.mat (bufferSize=10) --- info: 0 warnings --- info: 1 errors -- endResult diff --git a/testsuite/OMSimulator/partialSnapshot.lua b/testsuite/OMSimulator/partialSnapshot.lua new file mode 100644 index 000000000..cf80037d4 --- /dev/null +++ b/testsuite/OMSimulator/partialSnapshot.lua @@ -0,0 +1,287 @@ +-- status: correct +-- linux: yes +-- mingw: yes +-- win: no +-- mac: no + +oms_setCommandLineOption("--suppressPath=true --exportParametersInline=false") +oms_setTempDirectory("./partial_snapshot_lua/") + +oms_newModel("snapshot") +oms_addSystem("snapshot.root", oms_system_wc) + +oms_addConnector("snapshot.root.C1", oms_causality_input, oms_signal_type_real) +oms_setReal("snapshot.root.C1", -10) + +oms_addSubModel("snapshot.root.add", "../resources/Modelica.Blocks.Math.Add.fmu") +oms_setReal("snapshot.root.add.u1", 10) +oms_setReal("snapshot.root.add.k1", 30) + +-- correct, querying full model +snapshot = oms_exportSnapshot("snapshot") +print(snapshot) + +-- correct, querying partial snapshot ".ssd" +snapshot = oms_exportSnapshot("snapshot:SystemStructure.ssd") +print(snapshot) + +-- correct, querying partial snapshot ".ssv" +snapshot = oms_exportSnapshot("snapshot:resources/snapshot.ssv") +print(snapshot) + +-- error querying wrong resources +oms_exportSnapshot("snapshot:resources/snapshot1.ssv") + +-- error querying wrong model +oms_exportSnapshot("snapshot1:resources/snapshot1.ssv") + +-- query system +snapshot = oms_exportSnapshot("snapshot.root:SystemStructure.ssd") +print(snapshot) + +-- query sub component +snapshot = oms_exportSnapshot("snapshot.root.add:SystemStructure.ssd") +print(snapshot) + +-- TODO error messages for querying wrong subsystems or components +-- snapshot = oms_exportSnapshot("snapshot.root.add1:SystemStructure.ssd") + + +-- Result: +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- error: [getResourceNode] Failed to find node "resources/snapshot1.ssv" +-- error: [exportPartialSnapshot] Failed to find node "resources/snapshot1.ssv" +-- error: [oms_exportSnapshot] Model "snapshot1:resources/snapshot1.ssv" does not exist in the scope +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- +-- info: 0 warnings +-- info: 3 errors +-- endResult diff --git a/testsuite/OMSimulator/snapshot.lua b/testsuite/OMSimulator/snapshot.lua index 43bd395a4..a0a128068 100644 --- a/testsuite/OMSimulator/snapshot.lua +++ b/testsuite/OMSimulator/snapshot.lua @@ -30,7 +30,7 @@ oms_delete("snapshot") -- Result: -- --- +-- -- -- -- diff --git a/testsuite/OMSimulator/snapshot.py b/testsuite/OMSimulator/snapshot.py index f10c38b2d..1fdd70b00 100644 --- a/testsuite/OMSimulator/snapshot.py +++ b/testsuite/OMSimulator/snapshot.py @@ -34,7 +34,7 @@ ## Result: ## -## +## ## ## ##