urbanopt-reporting 0.4.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +21 -1
  3. data/LICENSE.md +17 -17
  4. data/doc_templates/LICENSE.md +17 -17
  5. data/doc_templates/copyright_erb.txt +2 -2
  6. data/doc_templates/copyright_js.txt +2 -2
  7. data/doc_templates/copyright_ruby.txt +1 -1
  8. data/docs/package-lock.json +15717 -1407
  9. data/lib/measures/.rubocop.yml +4 -2
  10. data/lib/measures/default_feature_reports/measure.rb +101 -36
  11. data/lib/measures/export_modelica_loads/measure.rb +2 -1
  12. data/lib/measures/export_time_series_modelica/measure.rb +58 -59
  13. data/lib/measures/export_time_series_modelica/resources/os_lib_helper_methods.rb +3 -5
  14. data/lib/urbanopt/reporting/default_reports/construction_cost.rb +2 -1
  15. data/lib/urbanopt/reporting/default_reports/date.rb +2 -1
  16. data/lib/urbanopt/reporting/default_reports/distributed_generation.rb +25 -7
  17. data/lib/urbanopt/reporting/default_reports/end_use.rb +1 -1
  18. data/lib/urbanopt/reporting/default_reports/end_uses.rb +2 -1
  19. data/lib/urbanopt/reporting/default_reports/extension.rb +1 -1
  20. data/lib/urbanopt/reporting/default_reports/feature_report.rb +9 -8
  21. data/lib/urbanopt/reporting/default_reports/generator.rb +1 -2
  22. data/lib/urbanopt/reporting/default_reports/location.rb +2 -1
  23. data/lib/urbanopt/reporting/default_reports/logger.rb +2 -2
  24. data/lib/urbanopt/reporting/default_reports/power_distribution.rb +22 -6
  25. data/lib/urbanopt/reporting/default_reports/program.rb +2 -1
  26. data/lib/urbanopt/reporting/default_reports/reporting_period.rb +30 -7
  27. data/lib/urbanopt/reporting/default_reports/scenario_power_distribution.rb +148 -0
  28. data/lib/urbanopt/reporting/default_reports/scenario_report.rb +20 -14
  29. data/lib/urbanopt/reporting/default_reports/schema/scenario_csv_columns.txt +18 -0
  30. data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +240 -6
  31. data/lib/urbanopt/reporting/default_reports/solar_pv.rb +42 -3
  32. data/lib/urbanopt/reporting/default_reports/storage.rb +1 -1
  33. data/lib/urbanopt/reporting/default_reports/thermal_storage.rb +1 -1
  34. data/lib/urbanopt/reporting/default_reports/timeseries_csv.rb +2 -1
  35. data/lib/urbanopt/reporting/default_reports/validator.rb +1 -1
  36. data/lib/urbanopt/reporting/default_reports/wind.rb +11 -2
  37. data/lib/urbanopt/reporting/default_reports.rb +1 -1
  38. data/lib/urbanopt/reporting/derived_extension.rb +1 -1
  39. data/lib/urbanopt/reporting/version.rb +2 -2
  40. data/lib/urbanopt/reporting.rb +1 -1
  41. data/urbanopt-reporting-gem.gemspec +3 -4
  42. metadata +16 -15
@@ -1,5 +1,7 @@
1
1
  AllCops:
2
2
  Exclude:
3
- - 'spec/test_measures/**/*'
3
+ - gems/**/*
4
+ require: rubocop-performance
5
+
4
6
  inherit_from:
5
- - http://s3.amazonaws.com/openstudio-resources/styles/rubocop_v3.yml
7
+ - http://s3.amazonaws.com/openstudio-resources/styles/rubocop_v4.yml
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -43,7 +43,7 @@ require 'csv'
43
43
  require 'benchmark'
44
44
  require 'logger'
45
45
 
46
- @@logger = Logger.new(STDOUT)
46
+ @@logger = Logger.new($stdout)
47
47
 
48
48
  # start the measure
49
49
  class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
@@ -240,7 +240,11 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
240
240
 
241
241
  ev_timeseries_data = ['Exterior Equipment:Electric Vehicles']
242
242
 
243
+ emissions_timeseries_data = ['Future_Annual_Emissions_Var', 'Future_Hourly_Emissions_Var', 'Historical_Annual_Emissions_Var', 'Historical_Hourly_Emissions_Var',
244
+ 'Future_Annual_Emissions_Intensity_Var', 'Future_Hourly_Emissions_Intensity_Var', 'Historical_Annual_Emissions_Intensity_Var', 'Historical_Hourly_Emissions_Intensity_Var']
245
+
243
246
  timeseries_data += tes_timeseries_data
247
+ timeseries_data += emissions_timeseries_data
244
248
 
245
249
  timeseries_data.each do |ts|
246
250
  result << OpenStudio::IdfObject.load("Output:Variable,*,#{ts},#{reporting_frequency};").get
@@ -277,6 +281,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
277
281
  if value.nil?
278
282
  return nil
279
283
  end
284
+
280
285
  if from_units.nil? || to_units.nil?
281
286
  @runner.registerError("Cannot convert units...from_units: #{from_units} or to_units: #{to_units} left blank.")
282
287
  return nil
@@ -343,6 +348,20 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
343
348
  sql_file = sql_file.get
344
349
  model.setSqlFile(sql_file)
345
350
 
351
+ # Get the weather file run period (as opposed to design day run period)
352
+ ann_env_pd = nil
353
+ sql_file.availableEnvPeriods.each do |env_pd|
354
+ env_type = sql_file.environmentType(env_pd)
355
+ if env_type.is_initialized && (env_type.get == OpenStudio::EnvironmentType.new('WeatherRunPeriod'))
356
+ ann_env_pd = env_pd
357
+ end
358
+ end
359
+
360
+ if ann_env_pd == false
361
+ runner.registerError("Can't find a weather runperiod, make sure you ran an annual simulation, not just the design days.")
362
+ return false
363
+ end
364
+
346
365
  # get building from model
347
366
  building = model.getBuilding
348
367
 
@@ -408,8 +427,8 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
408
427
  # unconditioned_area
409
428
  unconditioned_area = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Unconditioned Building Area' AND ColumnName='Area'")
410
429
  feature_report.program.unconditioned_area_sqft = convert_units(unconditioned_area, 'm^2', 'ft^2')
411
- if building.standardsBuildingType.is_initialized
412
- floor_area -= unconditioned_area if ['Residential'].include?(building.standardsBuildingType.get) # conditioned floor area only
430
+ if building.standardsBuildingType.is_initialized && ['Residential'].include?(building.standardsBuildingType.get)
431
+ floor_area -= unconditioned_area # conditioned floor area only
413
432
  end
414
433
 
415
434
  # maximum_number_of_stories
@@ -429,7 +448,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
429
448
 
430
449
  # footprint_area
431
450
  if building.standardsBuildingType.is_initialized
432
- if not ['Residential'].include?(building.standardsBuildingType.get)
451
+ if !['Residential'].include?(building.standardsBuildingType.get)
433
452
  feature_report.program.footprint_area_sqft = feature_report.program.floor_area_sqft / number_of_stories
434
453
  else
435
454
  feature_report.program.footprint_area_sqft = convert_units(floor_area, 'm^2', 'ft^2') / building.additionalProperties.getFeatureAsInteger('NumberOfConditionedStories').get
@@ -459,6 +478,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
459
478
  building_type = building_type.get
460
479
  end
461
480
  next if ['Residential'].include?(building_type) # space types with empty building type fields will inherit from the building object
481
+
462
482
  space_type_areas[building_type] = 0 if space_type_areas[building_type].nil?
463
483
  space_type_areas[building_type] += convert_units(space_type.floorArea, 'm^2', 'ft^2')
464
484
  end
@@ -471,6 +491,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
471
491
  else
472
492
  building_type = space.spaceType.get.standardsBuildingType
473
493
  end
494
+
474
495
  if building_type.empty?
475
496
  building_type = 'unknown'
476
497
  else
@@ -689,15 +710,15 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
689
710
  # district_cooling
690
711
  district_cooling = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='District Cooling'")
691
712
  feature_report.reporting_periods[0].district_cooling_kwh = convert_units(district_cooling, 'GJ', 'kWh')
692
- if building.standardsBuildingType.is_initialized
693
- feature_report.reporting_periods[0].district_cooling_kwh = 0.0 if ['Residential'].include?(building.standardsBuildingType.get)
713
+ if building.standardsBuildingType.is_initialized && ['Residential'].include?(building.standardsBuildingType.get)
714
+ feature_report.reporting_periods[0].district_cooling_kwh = 0.0
694
715
  end
695
716
 
696
717
  # district_heating
697
718
  district_heating = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='District Heating'")
698
719
  feature_report.reporting_periods[0].district_heating_kwh = convert_units(district_heating, 'GJ', 'kWh')
699
- if building.standardsBuildingType.is_initialized
700
- feature_report.reporting_periods[0].district_heating_kwh = 0.0 if ['Residential'].include?(building.standardsBuildingType.get)
720
+ if building.standardsBuildingType.is_initialized && ['Residential'].include?(building.standardsBuildingType.get)
721
+ feature_report.reporting_periods[0].district_heating_kwh = 0.0
701
722
  end
702
723
 
703
724
  # water
@@ -725,10 +746,10 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
725
746
  # report each query in its corresponding feature report obeject
726
747
  x = ft.tr(' ', '_').downcase
727
748
  if x.include? 'water'
728
- x_u = x + '_qbft'
729
- else
749
+ x_u = "#{x}_qbft"
750
+ else
730
751
  x = x.gsub('_#2', '')
731
- x_u = x + '_kwh'
752
+ x_u = "#{x}_kwh"
732
753
  end
733
754
  m = feature_report.reporting_periods[0].end_uses.send(x_u)
734
755
 
@@ -739,8 +760,8 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
739
760
  end
740
761
  sql_r = convert_units(sql_r, 'GJ', 'kWh')
741
762
 
742
- if building.standardsBuildingType.is_initialized
743
- sql_r = 0.0 if ['Residential'].include?(building.standardsBuildingType.get) && x_u.include?('district')
763
+ if building.standardsBuildingType.is_initialized && (['Residential'].include?(building.standardsBuildingType.get) && x_u.include?('district'))
764
+ sql_r = 0.0
744
765
  end
745
766
  m.send("#{y}=", sql_r)
746
767
  end
@@ -755,7 +776,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
755
776
  sql = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='#{eu}' AND ColumnName='#{ft}'")
756
777
 
757
778
  # ensure not nil so the equations below don't error out
758
- if not sql.nil?
779
+ if !sql.nil?
759
780
  sql_r += convert_units(sql, 'GJ', 'kWh')
760
781
  end
761
782
  end
@@ -798,23 +819,43 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
798
819
  time_setpoint_not_met_during_occupied_hours = time_setpoint_not_met_during_occupied_heating + time_setpoint_not_met_during_occupied_cooling
799
820
  feature_report.reporting_periods[0].comfort_result[:time_setpoint_not_met_during_occupied_hours] = time_setpoint_not_met_during_occupied_hours
800
821
 
801
- ######################################## Reporting TImeseries Results FOR CSV File ######################################
802
-
803
- # Get the weather file run period (as opposed to design day run period)
804
- ann_env_pd = nil
805
- sql_file.availableEnvPeriods.each do |env_pd|
806
- env_type = sql_file.environmentType(env_pd)
807
- if env_type.is_initialized
808
- if env_type.get == OpenStudio::EnvironmentType.new('WeatherRunPeriod')
809
- ann_env_pd = env_pd
810
- end
811
- end
812
- end
813
-
814
- if ann_env_pd == false
815
- runner.registerError("Can't find a weather runperiod, make sure you ran an annual simulation, not just the design days.")
816
- return false
822
+ # #emissions
823
+ begin
824
+ # future_annual_emissions
825
+ future_annual_emissions_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Future_Annual_Emissions_Var', 'EMS')
826
+ feature_report.reporting_periods[0].emissions[:future_annual_emissions_mt] = future_annual_emissions_ts.get.values.sum
827
+
828
+ # future_hourly_emissions
829
+ future_hourly_emissions_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Future_Hourly_Emissions_Var', 'EMS')
830
+ feature_report.reporting_periods[0].emissions[:future_hourly_emissions_mt] = future_hourly_emissions_ts.get.values.sum
831
+
832
+ # historical_annual_emissions
833
+ historical_annual_emissions_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Historical_Annual_Emissions_Var', 'EMS')
834
+ feature_report.reporting_periods[0].emissions[:historical_annual_emissions_mt] = historical_annual_emissions_ts.get.values.sum
835
+
836
+ # historical_annual_emissions
837
+ historical_hourly_emissions_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Historical_Hourly_Emissions_Var', 'EMS')
838
+ feature_report.reporting_periods[0].emissions[:historical_hourly_emissions_mt] = historical_hourly_emissions_ts.get.values.sum
839
+
840
+ # future_annual_emissions
841
+ future_annual_emissions_intensity_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Future_Annual_Emissions_Intensity_Var', 'EMS')
842
+ feature_report.reporting_periods[0].emissions[:future_annual_emissions_intensity_kg_per_ft2] = future_annual_emissions_intensity_ts.get.values.sum
843
+
844
+ # future_hourly_emissions
845
+ future_hourly_emissions_intensity_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Future_Hourly_Emissions_Intensity_Var', 'EMS')
846
+ feature_report.reporting_periods[0].emissions[:future_hourly_emissions_intensity_kg_per_ft2] = future_hourly_emissions_intensity_ts.get.values.sum
847
+
848
+ # historical_annual_emissions
849
+ historical_annual_emissions_intensity_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Historical_Annual_Emissions_Intensity_Var', 'EMS')
850
+ feature_report.reporting_periods[0].emissions[:historical_annual_emissions_intensity_kg_per_ft2] = historical_annual_emissions_intensity_ts.get.values.sum
851
+
852
+ # historical_annual_emissions
853
+ historical_hourly_emissions_intensity_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Historical_Hourly_Emissions_Intensity_Var', 'EMS')
854
+ feature_report.reporting_periods[0].emissions[:historical_hourly_emissions_intensity_kg_per_ft2] = historical_hourly_emissions_intensity_ts.get.values.sum
855
+ rescue StandardError
856
+ @@logger.info('Emissions are not reported for this feature')
817
857
  end
858
+ ######################################## Reporting TImeseries Results FOR CSV File #######################################
818
859
 
819
860
  # timeseries we want to report
820
861
  requested_timeseries_names = [
@@ -861,7 +902,25 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
861
902
  'District Heating Inlet Temperature',
862
903
  'District Heating Outlet Temperature',
863
904
  'Cooling Coil Total Cooling Rate',
864
- 'Heating Coil Heating Rate'
905
+ 'Heating Coil Heating Rate',
906
+ 'Future_Annual_Emissions_Var',
907
+ 'Future_Hourly_Emissions_Var',
908
+ 'Historical_Annual_Emissions_Var',
909
+ 'Historical_Hourly_Emissions_Var',
910
+ 'Future_Annual_Emissions_Intensity_Var',
911
+ 'Future_Hourly_Emissions_Intensity_Var',
912
+ 'Historical_Annual_Emissions_Intensity_Var',
913
+ 'Historical_Hourly_Emissions_Intensity_Var',
914
+ 'Curtailed EV Power',
915
+ 'Daily EV Charge Energy Capacity',
916
+ 'EV Charge Ratio',
917
+ 'Total Charged EV Energy',
918
+ 'Total Curtailed EV Energy',
919
+ 'Total Scheduled EV Energy',
920
+ 'Emission Intensity Schedule Output',
921
+ 'EV Charging Effective Schedule',
922
+ 'EV Charging Original Schedule',
923
+ 'EV Charging Original Load'
865
924
  ]
866
925
 
867
926
  # add thermal comfort timeseries
@@ -954,7 +1013,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
954
1013
  # use key_value name
955
1014
  # special case for Zone Thermal Comfort: use both timeseries_name and key_value
956
1015
  if timeseries_name.include? 'Zone Thermal Comfort'
957
- new_timeseries_name = timeseries_name + ' ' + key_value
1016
+ new_timeseries_name = "#{timeseries_name} #{key_value}"
958
1017
  else
959
1018
  new_timeseries_name = key_value
960
1019
  end
@@ -982,8 +1041,8 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
982
1041
  end
983
1042
 
984
1043
  # residential considerations
985
- if building.standardsBuildingType.is_initialized
986
- values[key_cnt] = Array.new(n, 0) if ['DistrictCooling:Facility', 'DistrictHeating:Facility'].include?(timeseries_name) && ['Residential'].include?(building.standardsBuildingType.get)
1044
+ if building.standardsBuildingType.is_initialized && (['DistrictCooling:Facility', 'DistrictHeating:Facility'].include?(timeseries_name) && ['Residential'].include?(building.standardsBuildingType.get))
1045
+ values[key_cnt] = Array.new(n, 0)
987
1046
  end
988
1047
 
989
1048
  # unit conversion
@@ -1001,7 +1060,13 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1001
1060
  'm3'
1002
1061
  when 'W'
1003
1062
  'W'
1004
- end
1063
+ when 'kg'
1064
+ 'kg'
1065
+ when 'MT'
1066
+ 'MT'
1067
+ when 'KG/FT2'
1068
+ 'KG/FT2'
1069
+ end
1005
1070
  end
1006
1071
 
1007
1072
  # loop through each value and apply unit conversion
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -337,6 +337,7 @@ class ExportModelicaLoads < OpenStudio::Measure::ReportingMeasure
337
337
  f << "double tab1(8760,4)\n"
338
338
  modelica_data.each_with_index do |row, index|
339
339
  next if index.zero?
340
+
340
341
  f << row.join(';') << "\n"
341
342
  end
342
343
  end
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -40,11 +40,10 @@
40
40
 
41
41
  require 'erb'
42
42
 
43
-
44
43
  # This measure is originally from https://github.com/urbanopt/DES_HVAC
45
44
  # start the measure
46
45
  class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
47
- Dir[File.dirname(__FILE__) + '/resources/*.rb'].each { |file| require file }
46
+ Dir["#{File.dirname(__FILE__)}/resources/*.rb"].sort.each { |file| require file }
48
47
  include OsLib_HelperMethods
49
48
  # human readable name
50
49
  def name
@@ -75,12 +74,12 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
75
74
  hhw_loop_name.setDefaultValue('hot')
76
75
  args << hhw_loop_name
77
76
 
78
- chw_loop_name = OpenStudio::Measure::OSArgument.makeStringArgument('chw_loop_name', true)
77
+ chw_loop_name = OpenStudio::Measure::OSArgument.makeStringArgument('chw_loop_name', true)
79
78
  chw_loop_name.setDisplayName('Name or Partial Name of Chilled Water Loop, non-case-sensitive')
80
79
  chw_loop_name.setDefaultValue('chilled')
81
80
  args << chw_loop_name
82
81
 
83
- dec_places_mass_flow = OpenStudio::Measure::OSArgument.makeIntegerArgument('dec_places_mass_flow', true)
82
+ dec_places_mass_flow = OpenStudio::Measure::OSArgument.makeIntegerArgument('dec_places_mass_flow', true)
84
83
  dec_places_mass_flow.setDisplayName('Number of Decimal Places to Round Mass Flow Rate')
85
84
  dec_places_mass_flow.setDescription('Number of decimal places to which mass flow rate will be rounded')
86
85
  dec_places_mass_flow.setDefaultValue(3)
@@ -113,11 +112,11 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
113
112
  # use the built-in error checking
114
113
  return false unless runner.validateUserArguments(arguments(model), user_arguments)
115
114
 
116
- ##Read in argumetns related to variables for output requests
115
+ # #Read in argumetns related to variables for output requests
117
116
  hhw_loop_name = runner.getStringArgumentValue('hhw_loop_name', user_arguments)
118
117
  chw_loop_name = runner.getStringArgumentValue('chw_loop_name', user_arguments)
119
118
 
120
- #Identify key names for output variables.
119
+ # Identify key names for output variables.
121
120
  plantloops = model.getPlantLoops
122
121
 
123
122
  selected_plant_loops = []
@@ -128,19 +127,19 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
128
127
  reporting_frequency = 'timestep'
129
128
 
130
129
  plantloops.each do |plantLoop|
131
- log "plant loop name #{plantLoop.name.get.to_s}"
130
+ log "plant loop name #{plantLoop.name.get}"
132
131
  if plantLoop.name.get.to_s.downcase.include? chw_loop_name.to_s
133
- #Extract plant loop information
134
- selected_plant_loops[0]=plantLoop
132
+ # Extract plant loop information
133
+ selected_plant_loops[0] = plantLoop
135
134
  key_value_chw_outlet = selected_plant_loops[0].demandOutletNode.name.to_s
136
135
  key_value_chw_inlet = selected_plant_loops[0].demandInletNode.name.to_s
137
136
  result << OpenStudio::IdfObject.load("Output:Variable,#{key_value_chw_outlet},#{variable_name2},timestep;").get
138
137
  result << OpenStudio::IdfObject.load("Output:Variable,#{key_value_chw_inlet},#{variable_name2},timestep;").get
139
138
  result << OpenStudio::IdfObject.load("Output:Variable,#{key_value_chw_outlet},#{variable_name1},timestep;").get
140
139
  end
141
- if plantLoop.name.get.to_s.downcase.include? hhw_loop_name.to_s and !plantLoop.name.get.to_s.downcase.include? "service" and !plantLoop.name.get.to_s.downcase.include? "domestic"
142
- #Extract plant loop information
143
- selected_plant_loops[1]=plantLoop
140
+ if plantLoop.name.get.to_s.downcase.include?(hhw_loop_name.to_s) && !plantLoop.name.get.to_s.downcase.include?('service') && !plantLoop.name.get.to_s.downcase.include?('domestic')
141
+ # Extract plant loop information
142
+ selected_plant_loops[1] = plantLoop
144
143
  key_value_hhw_outlet = selected_plant_loops[1].demandOutletNode.name.to_s
145
144
  key_value_hhw_inlet = selected_plant_loops[1].demandInletNode.name.to_s
146
145
  result << OpenStudio::IdfObject.load("Output:Variable,#{key_value_hhw_outlet},#{variable_name2},timestep;").get
@@ -153,7 +152,7 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
153
152
  result << OpenStudio::IdfObject.load('Output:Variable,,Site Outdoor Air Drybulb Temperature,hourly;').get
154
153
  result << OpenStudio::IdfObject.load('Output:Variable,,Site Outdoor Air Relative Humidity,hourly;').get
155
154
  result << OpenStudio::IdfObject.load('Output:Meter,Cooling:Electricity,hourly;').get
156
- result << OpenStudio::IdfObject.load('Output:Meter,Electricity:Facility,timestep;').get ##Using this for data at timestep interval
155
+ result << OpenStudio::IdfObject.load('Output:Meter,Electricity:Facility,timestep;').get # #Using this for data at timestep interval
157
156
  result << OpenStudio::IdfObject.load('Output:Meter,Heating:Electricity,hourly;').get
158
157
  result << OpenStudio::IdfObject.load('Output:Meter,Heating:NaturalGas,hourly;').get
159
158
  result << OpenStudio::IdfObject.load('Output:Meter,InteriorLights:Electricity,hourly;').get
@@ -171,15 +170,15 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
171
170
  result
172
171
  end
173
172
 
174
- def extract_timeseries_into_matrix(sqlfile, data, variable_name, str, key_value = nil, default_if_empty = 0,dec_places, timestep)
173
+ def extract_timeseries_into_matrix(sqlfile, data, variable_name, str, key_value = nil, default_if_empty = 0, dec_places, timestep)
175
174
  log "Executing query for #{variable_name}"
176
- #column_name = variable_name
175
+ # column_name = variable_name
177
176
  if key_value
178
177
  ts = sqlfile.timeSeries('RUN PERIOD 1', 'Zone Timestep', variable_name, key_value)
179
- #column_name += "_#{key_value}"
180
- column_name=str
178
+ # column_name += "_#{key_value}"
179
+ column_name = str
181
180
  else
182
- #ts = sqlfile.timeSeries('RUN PERIOD 1', 'Hourly', variable_name)
181
+ # ts = sqlfile.timeSeries('RUN PERIOD 1', 'Hourly', variable_name)
183
182
  ts = sqlfile.timeSeries('RUN PERIOD 1', 'Zone Timestep', variable_name)
184
183
  end
185
184
  log 'Iterating over timeseries'
@@ -201,16 +200,16 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
201
200
  # end
202
201
 
203
202
  quick_proc = ts.values.to_s.split(',')
204
- quick_proc[0]=quick_proc[0].split('(', 2).last #cleanup necessary to remove opening paren
205
- quick_proc=quick_proc.map(&:to_f)
203
+ quick_proc[0] = quick_proc[0].split('(', 2).last # cleanup necessary to remove opening paren
204
+ quick_proc = quick_proc.map(&:to_f)
206
205
  x = 0
207
206
  len = quick_proc.length
208
- log "quick proc #{quick_proc}"
209
- while(x < len) #Round to the # of decimal places specified
210
- quick_proc[x]=(quick_proc[x]).round(dec_places)
211
- x=x+1
212
- end
213
- quick_proc=quick_proc.map(&:to_s)
207
+ log "quick proc #{quick_proc}"
208
+ while x < len # Round to the # of decimal places specified
209
+ quick_proc[x] = (quick_proc[x]).round(dec_places)
210
+ x += 1
211
+ end
212
+ quick_proc = quick_proc.map(&:to_s)
214
213
 
215
214
  # the first and last have some cleanup items because of the Vector method
216
215
  quick_proc[0] = quick_proc[0].gsub(/^.*\(/, '')
@@ -232,7 +231,7 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
232
231
  log "Finished extracting #{variable_name}"
233
232
  end
234
233
 
235
- def create_new_variable_sum(data, new_var_name, include_str, options=nil)
234
+ def create_new_variable_sum(data, new_var_name, include_str, options = nil)
236
235
  var_info = {
237
236
  name: new_var_name,
238
237
  var_indexes: []
@@ -285,16 +284,18 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
285
284
 
286
285
  # lookup and replace argument values from upstream measures
287
286
  if args['use_upstream_args'] == true
288
- args.each do |arg,value|
287
+ args.each do |arg, value|
289
288
  next if arg == 'use_upstream_args' # this argument should not be changed
289
+
290
290
  value_from_osw = OsLib_HelperMethods.check_upstream_measure_for_arg(runner, arg)
291
291
  if !value_from_osw.empty?
292
292
  runner.registerInfo("Replacing argument named #{arg} from current measure with a value of #{value_from_osw[:value]} from #{value_from_osw[:measure_name]}.")
293
293
  new_val = value_from_osw[:value]
294
294
  # TODO: make code to handle non strings more robust. check_upstream_measure_for_arg could pass back the argument type
295
- if arg == 'hhw_loop_name'
295
+ case arg
296
+ when 'hhw_loop_name'
296
297
  args[arg] = new_val.to_s
297
- elsif arg == 'chw_loop_name'
298
+ when 'chw_loop_name'
298
299
  args[arg] = new_val.to_s
299
300
  else
300
301
  args[arg] = new_val
@@ -314,8 +315,8 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
314
315
  end
315
316
  model = model.get
316
317
 
317
- timesteps_per_hour=model.getTimestep.numberOfTimestepsPerHour.to_i
318
- timestep=60/timesteps_per_hour #timestep in minutes
318
+ timesteps_per_hour = model.getTimestep.numberOfTimestepsPerHour.to_i
319
+ timestep = 60 / timesteps_per_hour # timestep in minutes
319
320
 
320
321
  sqlFile = runner.lastEnergyPlusSqlFile
321
322
  if sqlFile.empty?
@@ -342,7 +343,7 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
342
343
  ts = sqlFile.timeSeries('RUN PERIOD 1', 'Zone Timestep', attribute_name)
343
344
  if ts.empty?
344
345
  runner.registerError("This feature does not have the attribute '#{attribute_name}' to enable this measure to work." \
345
- "To resolve, simulate a building with electricity or remove this measure from your workflow.")
346
+ 'To resolve, simulate a building with electricity or remove this measure from your workflow.')
346
347
  else
347
348
  ts = ts.first
348
349
  dt_base = nil
@@ -357,7 +358,7 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
357
358
  dt.date.dayOfWeek.value,
358
359
  dt.time.hours,
359
360
  dt.time.minutes,
360
- dt_current.to_time.to_i - dt_base.to_time.to_i + timestep*60
361
+ dt_current.to_time.to_i - dt_base.to_time.to_i + timestep * 60
361
362
  ]
362
363
  end
363
364
  end
@@ -367,52 +368,51 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
367
368
  selected_plant_loops = []
368
369
  i = 0
369
370
 
370
- key_var={}
371
+ key_var = {}
371
372
 
372
373
  plantloops.each do |plantLoop|
373
374
  if plantLoop.name.get.to_s.downcase.include? chw_loop_name.to_str
374
- #Extract plant loop information
375
- selected_plant_loops[0]=plantLoop
375
+ # Extract plant loop information
376
+ selected_plant_loops[0] = plantLoop
376
377
  end
377
378
  if plantLoop.name.get.to_s.downcase.include? hhw_loop_name.to_str
378
- #Get plant loop information
379
- selected_plant_loops[1]=plantLoop
379
+ # Get plant loop information
380
+ selected_plant_loops[1] = plantLoop
380
381
  end
381
382
  end
382
383
 
383
384
  if !selected_plant_loops[1].nil?
384
- #Set up variables for output
385
+ # Set up variables for output
385
386
  key_value_hhw_outlet = selected_plant_loops[1].demandOutletNode.name.to_s
386
387
  key_value_hhw_inlet = selected_plant_loops[1].demandInletNode.name.to_s
387
- key_var['hhw_outlet_massflow']='massFlowRateHeating'
388
- key_var['hhw_outlet_temp']='heatingReturnTemperature[C]'
389
- key_var['hhw_inlet_temp']='heatingSupplyTemperature[C]'
390
- #Extract time series
388
+ key_var['hhw_outlet_massflow'] = 'massFlowRateHeating'
389
+ key_var['hhw_outlet_temp'] = 'heatingReturnTemperature[C]'
390
+ key_var['hhw_inlet_temp'] = 'heatingSupplyTemperature[C]'
391
+ # Extract time series
391
392
  extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['hhw_outlet_temp'], key_value_hhw_outlet, 0, dec_places_temp, timestep)
392
393
  extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['hhw_inlet_temp'], key_value_hhw_inlet, 0, dec_places_temp, timestep)
393
394
  extract_timeseries_into_matrix(sqlFile, rows, 'System Node Mass Flow Rate', key_var['hhw_outlet_massflow'], key_value_hhw_outlet, 0, dec_places_mass_flow, timestep)
394
395
  else
395
- runner.registerWarning("No hot water loop found. If one is expected, make sure the hot water loop name argument provides a string present in its name.")
396
+ runner.registerWarning('No hot water loop found. If one is expected, make sure the hot water loop name argument provides a string present in its name.')
396
397
  end
397
398
 
398
399
  if !selected_plant_loops[0].nil?
399
- #Set up variables for outputs
400
+ # Set up variables for outputs
400
401
  key_value_chw_outlet = selected_plant_loops[0].demandOutletNode.name.to_s
401
402
  key_value_chw_inlet = selected_plant_loops[0].demandInletNode.name.to_s
402
- key_var['chw_outlet_massflow']='massFlowRateCooling'
403
- key_var['chw_outlet_temp']='ChilledWaterReturnTemperature[C]'
404
- key_var['chw_inlet_temp']='ChilledWaterSupplyTemperature[C]'
405
- #Extract time series
406
- extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['chw_outlet_temp'], key_value_chw_outlet, 0, dec_places_temp,timestep)
407
- extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['chw_inlet_temp'], key_value_chw_inlet, 0, dec_places_temp,timestep)
408
- extract_timeseries_into_matrix(sqlFile, rows, 'System Node Mass Flow Rate', key_var['chw_outlet_massflow'], key_value_chw_outlet, 0, dec_places_mass_flow,timestep)
403
+ key_var['chw_outlet_massflow'] = 'massFlowRateCooling'
404
+ key_var['chw_outlet_temp'] = 'ChilledWaterReturnTemperature[C]'
405
+ key_var['chw_inlet_temp'] = 'ChilledWaterSupplyTemperature[C]'
406
+ # Extract time series
407
+ extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['chw_outlet_temp'], key_value_chw_outlet, 0, dec_places_temp, timestep)
408
+ extract_timeseries_into_matrix(sqlFile, rows, 'System Node Temperature', key_var['chw_inlet_temp'], key_value_chw_inlet, 0, dec_places_temp, timestep)
409
+ extract_timeseries_into_matrix(sqlFile, rows, 'System Node Mass Flow Rate', key_var['chw_outlet_massflow'], key_value_chw_outlet, 0, dec_places_mass_flow, timestep)
409
410
  else
410
- runner.registerWarning("No chilled water loop found. If one is expected, make sure the chilled water loop name argument provides a string present in its name.")
411
+ runner.registerWarning('No chilled water loop found. If one is expected, make sure the chilled water loop name argument provides a string present in its name.')
411
412
  end
412
413
 
413
-
414
- if selected_plant_loops[0].nil? and selected_plant_loops[1].nil?
415
- runner.registerWarning("No HVAC plant loops found. If one or more plant loops are expected, make sure they follow the naming conventions mentioned in the previous warnings.")
414
+ if selected_plant_loops[0].nil? && selected_plant_loops[1].nil?
415
+ runner.registerWarning('No HVAC plant loops found. If one or more plant loops are expected, make sure they follow the naming conventions mentioned in the previous warnings.')
416
416
  end
417
417
 
418
418
  if !selected_plant_loops.nil?
@@ -430,6 +430,5 @@ class ExportTimeSeriesLoadsCSV < OpenStudio::Measure::ReportingMeasure
430
430
  end
431
431
  end
432
432
 
433
-
434
433
  # register the measure to be used by the application
435
434
  ExportTimeSeriesLoadsCSV.new.registerWithApplication
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -358,10 +358,8 @@ module OsLib_HelperMethods
358
358
  objectArray.each do |object|
359
359
  object_LCCs = object.lifeCycleCosts
360
360
  object_LCCs.each do |object_LCC|
361
- if object_LCC.category == category
362
- if onlyYearFromStartZero == false || object_LCC.yearsFromStart == 0
363
- counter += object_LCC.totalCost
364
- end
361
+ if object_LCC.category == category && (onlyYearFromStartZero == false || object_LCC.yearsFromStart == 0)
362
+ counter += object_LCC.totalCost
365
363
  end
366
364
  end
367
365
  end
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -50,6 +50,7 @@ module URBANopt
50
50
  ##
51
51
  class ConstructionCost
52
52
  attr_accessor :category, :item_name, :unit_cost, :cost_units, :item_quantity, :total_cost # :nodoc:
53
+
53
54
  ##
54
55
  # ConstructionCost class intialize all construction_cost attributes:
55
56
  # +:category+ , +:item_name+ , +:unit_cost+ , +:cost_units+ , +:item_quantity+ , +:total_cost+
@@ -1,5 +1,5 @@
1
1
  # *********************************************************************************
2
- # URBANopt™, Copyright (c) 2019-2021, Alliance for Sustainable Energy, LLC, and other
2
+ # URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
3
3
  # contributors. All rights reserved.
4
4
 
5
5
  # Redistribution and use in source and binary forms, with or without modification,
@@ -50,6 +50,7 @@ module URBANopt
50
50
  ##
51
51
  class Date
52
52
  attr_accessor :month, :day_of_month, :year #:nodoc:
53
+
53
54
  ##
54
55
  # Date class intialize all date attributes:
55
56
  # +:month+ , +:day_of_month+ , +:year+