From 5dd53c02d24da7571058701d55fa8e42bf3bc824 Mon Sep 17 00:00:00 2001 From: ThummeTo <83663542+ThummeTo@users.noreply.github.com> Date: Fri, 31 Jan 2025 11:26:20 +0100 Subject: [PATCH] fixing MD parsing (#132) * fixing MD parsing * updated LTS test, formatting * minor adaption * throw warning for unspoorted arrays/matrices --- .github/workflows/TestLatest.yml | 2 +- Project.toml | 2 +- src/FMI3/md.jl | 175 +++++++++++++++++++------------ 3 files changed, 111 insertions(+), 68 deletions(-) diff --git a/.github/workflows/TestLatest.yml b/.github/workflows/TestLatest.yml index 30c0ecd..bee9322 100644 --- a/.github/workflows/TestLatest.yml +++ b/.github/workflows/TestLatest.yml @@ -1,4 +1,4 @@ -name: Test v1 (latest) +name: Test (latest) on: workflow_dispatch: diff --git a/Project.toml b/Project.toml index f0b63f5..b3472db 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "FMIImport" uuid = "9fcbc62e-52a0-44e9-a616-1359a0008194" authors = ["TT ", "LM ", "JK "] -version = "1.0.8" +version = "1.0.9" [deps] Downloads = "f43a241f-c20a-4ad4-852c-f6b1247861c6" diff --git a/src/FMI3/md.jl b/src/FMI3/md.jl index 083a2b3..55a0cf3 100644 --- a/src/FMI3/md.jl +++ b/src/FMI3/md.jl @@ -288,17 +288,21 @@ function parseModelVariables(md::fmi3ModelDescription, nodes::EzXML.Node) modelVariables[index].clocks = parseArrayValueReferences(md, parseNode(node, "clocks", String)) - if typename ∉ ("Clock", "String") - modelVariables[index].intermediateUpdate = - parseNode(node, "intermediateUpdate", Bool) - else - @warn "Unsupported typename `$(typename)` for modelVariable attribute `intermediateUpdate`." + if haskey(node, "intermediateUpdate") + if typename ∉ ("Clock", "String") + modelVariables[index].intermediateUpdate = + parseNode(node, "intermediateUpdate", Bool) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `intermediateUpdate`." + end end - if typename ∉ ("Clock", "String") - modelVariables[index].previous = parseNode(node, "previous", Bool) - else - @warn "Unsupported typename `$(typename)` for modelVariable attribute `previous`." + if haskey(node, "previous") + if typename ∉ ("Clock", "String") + modelVariables[index].previous = parseNode(node, "previous", Bool) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `previous`." + end end if haskey(node, "initial") @@ -310,87 +314,126 @@ function parseModelVariables(md::fmi3ModelDescription, nodes::EzXML.Node) end end - if typename ∉ ("Clock", "String", "Binary", "Boolean") - modelVariables[index].quantity = parseNode(node, "quantity", String) - else - @warn "Unsupported typename `$(typename)` for modelVariable attribute `quantity`." + if haskey(node, "quantity") + if typename ∉ ("Clock", "String", "Binary", "Boolean") + modelVariables[index].quantity = parseNode(node, "quantity", String) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `quantity`." + end end - if typename == "Float64" || typename == "Float32" - modelVariables[index].unit = parseNode(node, "unit", String) - modelVariables[index].displayUnit = parseNode(node, "displayUnit", String) + if haskey(node, "unit") + if typename == "Float64" || typename == "Float32" + modelVariables[index].unit = parseNode(node, "unit", String) + modelVariables[index].displayUnit = parseNode(node, "displayUnit", String) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `unit`." + end end - if typename != "String" - modelVariables[index].declaredType = parseNode(node, "declaredType", String) - else - @warn "Unsupported typename `$(typename)` for modelVariable attribute `declaredType`." + if haskey(node, "declaredType") + if typename != "String" + modelVariables[index].declaredType = parseNode(node, "declaredType", String) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `declaredType`." + end end - if typename ∉ ("Clock", "String", "Binary", "Boolean") - modelVariables[index].min = - parseNode(node, "min", stringToDataType(md, typename)) - else - @warn "Unsupported typename `$(typename)` for modelVariable attribute `min`." + if haskey(node, "min") + if typename ∉ ("Clock", "String", "Binary", "Boolean") + modelVariables[index].min = + parseNode(node, "min", stringToDataType(md, typename)) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `min`." + end end - if typename ∉ ("Clock", "String", "Binary", "Boolean") - modelVariables[index].max = - parseNode(node, "max", stringToDataType(md, typename)) - else - @warn "Unsupported typename `$(typename)` for modelVariable attribute `max`." + if haskey(node, "max") + if typename ∉ ("Clock", "String", "Binary", "Boolean") + modelVariables[index].max = + parseNode(node, "max", stringToDataType(md, typename)) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `max`." + end end - if typename == "Float64" || typename == "Float32" - modelVariables[index].nominal = - parseNode(node, "nominal", stringToDataType(md, typename)) - modelVariables[index].unbounded = - parseNode(node, "unbounded", stringToDataType(md, typename)) + if haskey(node, "nominal") + if typename == "Float64" || typename == "Float32" + modelVariables[index].nominal = + parseNode(node, "nominal", stringToDataType(md, typename)) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `nominal`." + end end - if typename ∉ ("Binary", "Clock") - if !isnothing(node.firstelement) && node.firstelement.name == "Dimension" - substrings = split(node["start"], " ") + if haskey(node, "unbounded") + if typename == "Float64" || typename == "Float32" + modelVariables[index].unbounded = + parseNode(node, "unbounded", stringToDataType(md, typename)) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `unbounded`." + end + end - T = stringToDataType(md, typename) - modelVariables[index].start = Array{T}(undef, 0) - for string in substrings - push!(modelVariables[index].start, parseType(string, T)) + if haskey(node, "start") + if typename ∈ ("Binary", "Clock") + @warn "Unsupported typename `$(typename)` for modelVariable attribute `start`." + elseif typename == "Enum" + for i = 1:length(md.enumerations) + if modelVariables[index].declaredType == md.enumerations[i][1] # identify the enum by the name + modelVariables[index].start = + md.enumerations[i][1+parseNode(node, "start", Int)] # find the enum value and set it + end end - else - if typename == "Enum" - for i = 1:length(md.enumerations) - if modelVariables[index].declaredType == md.enumerations[i][1] # identify the enum by the name - modelVariables[index].start = - md.enumerations[i][1+parseNode(node, "start", Int)] # find the enum value and set it - end + elseif typename == "String" + for n in eachelement(node) + if n.name == "Start" + modelVariables[index].start = n["value"] + end + end + elseif typename == "Binary" + for n in eachelement(node) + if n.name == "Start" + modelVariables[index].start = pointer(n["value"]) + end + end + else # all "common" types + dimensions = Vector{UInt32}() + for element in eachelement(node) + if element.name == "Dimension" + push!(dimensions, parseType(element["start"], UInt32)) end + end + if length(dimensions) > 0 + # substrings = split(node["start"], " ") + + # T = stringToDataType(md, typename) + # modelVariables[index].start = Vector{T}() + # for string in substrings + # push!(modelVariables[index].start, parseType(string, T)) + # end + @warn "Parsing of multi-dimension variable start values not supported, yet.\nDimension is $(dimensions)" else modelVariables[index].start = parseNode(node, "start", stringToDataType(md, typename)) end end - else - @warn "Unsupported typename `$(typename)` for modelVariable attribute `start`." end - if typename == "Float64" || typename == "Float32" - modelVariables[index].derivative = - parseNode(node, "derivative", fmi3ValueReference) - modelVariables[index].reinit = parseNode(node, "reinit", Bool) + if haskey(node, "derivative") + if typename == "Float64" || typename == "Float32" + modelVariables[index].derivative = + parseNode(node, "derivative", fmi3ValueReference) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `derivative`." + end end - if typename == "String" - for nod in eachelement(node) - if nod.name == "Start" - modelVariables[index].start = nod["value"] - end - end - elseif typename == "Binary" - for nod in eachelement(node) - if nod.name == "Start" - modelVariables[index].start = pointer(nod["value"]) - end + if haskey(node, "reinit") + if typename == "Float64" || typename == "Float32" + modelVariables[index].reinit = parseNode(node, "reinit", Bool) + else + @warn "Unsupported typename `$(typename)` for modelVariable attribute `reinit`." end end