# ******************************************************************************* # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC. # See also https://openstudio.net/license # ******************************************************************************* # see the URL below for information on how to write OpenStudio measures # http://openstudio.nrel.gov/openstudio-measure-writing-guide # see the URL below for information on using life cycle cost objects in OpenStudio # http://openstudio.nrel.gov/openstudio-life-cycle-examples # see the URL below for access to C++ documentation on model objects (click on "model" in the main window to view model objects) # http://openstudio.nrel.gov/sites/openstudio.nrel.gov/files/nv_data/cpp_documentation_it/model/html/namespaces.html # start the measure class ReportModelChanges < OpenStudio::Measure::ModelMeasure # define the name that a user will see, this method may be deprecated as # the display name in PAT comes from the name field in measure.xml def name return 'ReportModelChanges' end # define the arguments that the user will input def arguments(model) args = OpenStudio::Measure::OSArgumentVector.new # make an argument for your name compare_model_path = OpenStudio::Measure::OSArgument.makeStringArgument('compare_model_path', true) compare_model_path.setDisplayName('Path to model for comparison') args << compare_model_path return args end # define what happens when the measure is run def run(model, runner, user_arguments) super(model, runner, user_arguments) # use the built-in error checking if !runner.validateUserArguments(arguments(model), user_arguments) return false end # assign the user inputs to variables compare_model_path = runner.getStringArgumentValue('compare_model_path', user_arguments) # load the model vt = OpenStudio::OSVersion::VersionTranslator.new compare_model = vt.loadModel(compare_model_path) if compare_model.empty? runner.registerError("Cannot load model from #{compare_model_path} for comparison.") return false end compare_model = compare_model.get only_model = [] only_compare = [] both = [] diffs = [] num_ignored = 0 # loop through model and find objects in this model only or in both model.getModelObjects.each do |object| # TODO: compare these some other way if !object.iddObject.hasNameField num_ignored += 1 next end compare_object = compare_model.getObjectByTypeAndName(object.iddObject.type, object.name.to_s) if compare_object.empty? only_model << object else both << [object, compare_object.get] end end # loop through model and find objects in comparison model only compare_model.getModelObjects.each do |compare_object| # TODO: compare these some other way if !compare_object.iddObject.hasNameField num_ignored += 1 next end object = model.getObjectByTypeAndName(compare_object.iddObject.type, compare_object.name.to_s) if object.empty? only_compare << compare_object end end # loop through and perform the diffs both.each do |b| object = b[0] compare_object = b[1] idd_object = object.iddObject object_num_fields = object.numFields compare_num_fields = compare_object.numFields diff = "\n" diff += "\n" diff += "\n" # loop over fields skipping handle same = true (1...[object_num_fields, compare_num_fields].max).each do |i| field_name = idd_object.getField(i).get.name object_value = '' if i < object_num_fields object_value = object.getString(i).to_s end object_value = '-' if object_value.empty? compare_value = '' if i < compare_num_fields compare_value = compare_object.getString(i).to_s end compare_value = '-' if compare_value.empty? row_color = 'green' if object_value != compare_value same = false row_color = 'red' end diff += "\n" end diff += "
#{object.iddObject.name}
Model ObjectComparison ObjectField Name
#{object_value}#{compare_value}#{field_name}

\n" if !same diffs << diff end end # path for reports report_path = Dir.pwd + '/report.html' # write the report File.open(report_path, 'w') do |file| file << "

\n

Objects Only In Model

\n" file << "\n" only_model.each do |object| file << "\n" end file << "
#{object}
\n" file << "
\n" file << "
\n

Objects Only In Comparison Model

\n" file << "\n" only_compare.each do |object| file << "\n" end file << "
#{object}
\n" file << "
\n" file << "
\n

Objects In Both Models With Differences

\n" diffs.each do |diff| file << diff end file << "
\n" end runner.registerInfo("Report generated at: #{report_path}") runner.registerWarning("#{num_ignored} objects did not have names and were not compared") return true end end # this allows the measure to be use by the application ReportModelChanges.new.registerWithApplication