urbanopt-reporting 0.4.3 → 0.6.1

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 +15720 -1410
  9. data/lib/measures/.rubocop.yml +4 -2
  10. data/lib/measures/default_feature_reports/measure.rb +242 -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 +24 -6
  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 +47 -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 +24 -0
  30. data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +265 -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
@@ -215,6 +215,8 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
215
215
  result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,NaturalGas:Facility,#{reporting_frequency};").get
216
216
  result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,DistrictCooling:Facility,#{reporting_frequency};").get
217
217
  result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,DistrictHeating:Facility,#{reporting_frequency};").get
218
+ result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Propane:Facility,#{reporting_frequency};").get
219
+ result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,FuelOilNo2:Facility,#{reporting_frequency};").get
218
220
 
219
221
  # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Cooling:Electricity,#{reporting_frequency};").get
220
222
  # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Heating:Electricity,#{reporting_frequency};").get
@@ -230,6 +232,15 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
230
232
  result << OpenStudio::IdfObject.load('Output:Variable,*,Heating Coil Heating Rate,hourly; !- HVAC Average [W];').get
231
233
  # result << OpenStudio::IdfObject.load("Output:Variable,*,Exterior Equipment:Electric Vehicles,#{reporting_frequency};").get
232
234
 
235
+ ## add environmental factor outputs
236
+ #result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Output:EnvironmentalImpactFactors,#{reporting_frequency};").get
237
+ # result << OpenStudio::IdfObject.load("Output:Variable,*,Environmental Impact Total N2O Emissions Carbon Equivalent Mass,#{reporting_frequency}; !- HVAC Sum [kg];").get
238
+ # result << OpenStudio::IdfObject.load("Output:Variable,*,Environmental Impact Total CH4 Emissions Carbon Equivalent Mass,#{reporting_frequency}; !- HVAC Sum [kg];").get
239
+ # result << OpenStudio::IdfObject.load("Output:Variable,*,Environmental Impact Total CO2 Emissions Carbon Equivalent Mass,#{reporting_frequency}; !- HVAC Sum [kg];").get
240
+ # result << OpenStudio::IdfObject.load("Output:Variable,*,Environmental Impact NaturalGas CO2 Emissions Mass,#{reporting_frequency}; !- HVAC Sum [kg];").get
241
+ # result << OpenStudio::IdfObject.load("Output:Variable,*,Environmental Impact NaturalGas CH4 Emissions Mass,#{reporting_frequency}; !- HVAC Sum [kg];").get
242
+ # result << OpenStudio::IdfObject.load("Output:Variable,*,Environmental Impact NaturalGas N2O Emissions Mass,#{reporting_frequency}; !- HVAC Sum [kg];").get
243
+
233
244
  timeseries_data = ['District Cooling Chilled Water Rate', 'District Cooling Mass Flow Rate',
234
245
  'District Cooling Inlet Temperature', 'District Cooling Outlet Temperature',
235
246
  'District Heating Hot Water Rate', 'District Heating Mass Flow Rate',
@@ -240,7 +251,15 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
240
251
 
241
252
  ev_timeseries_data = ['Exterior Equipment:Electric Vehicles']
242
253
 
254
+ emissions_timeseries_data = ['Future_Annual_Electricity_Emissions', 'Future_Hourly_Electricity_Emissions',
255
+ 'Historical_Annual_Electricity_Emissions', 'Historical_Hourly_Electricity_Emissions',
256
+ 'Future_Annual_Electricity_Emissions_Intensity', 'Future_Hourly_Electricity_Emissions_Intensity',
257
+ 'Historical_Annual_Electricity_Emissions_Intensity', 'Historical_Hourly_Electricity_Emissions_Intensity']
258
+
259
+
260
+
243
261
  timeseries_data += tes_timeseries_data
262
+ timeseries_data += emissions_timeseries_data
244
263
 
245
264
  timeseries_data.each do |ts|
246
265
  result << OpenStudio::IdfObject.load("Output:Variable,*,#{ts},#{reporting_frequency};").get
@@ -277,6 +296,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
277
296
  if value.nil?
278
297
  return nil
279
298
  end
299
+
280
300
  if from_units.nil? || to_units.nil?
281
301
  @runner.registerError("Cannot convert units...from_units: #{from_units} or to_units: #{to_units} left blank.")
282
302
  return nil
@@ -343,6 +363,20 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
343
363
  sql_file = sql_file.get
344
364
  model.setSqlFile(sql_file)
345
365
 
366
+ # Get the weather file run period (as opposed to design day run period)
367
+ ann_env_pd = nil
368
+ sql_file.availableEnvPeriods.each do |env_pd|
369
+ env_type = sql_file.environmentType(env_pd)
370
+ if env_type.is_initialized && (env_type.get == OpenStudio::EnvironmentType.new('WeatherRunPeriod'))
371
+ ann_env_pd = env_pd
372
+ end
373
+ end
374
+
375
+ if ann_env_pd == false
376
+ runner.registerError("Can't find a weather runperiod, make sure you ran an annual simulation, not just the design days.")
377
+ return false
378
+ end
379
+
346
380
  # get building from model
347
381
  building = model.getBuilding
348
382
 
@@ -408,8 +442,8 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
408
442
  # unconditioned_area
409
443
  unconditioned_area = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='Building Area' AND RowName='Unconditioned Building Area' AND ColumnName='Area'")
410
444
  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
445
+ if building.standardsBuildingType.is_initialized && ['Residential'].include?(building.standardsBuildingType.get)
446
+ floor_area -= unconditioned_area # conditioned floor area only
413
447
  end
414
448
 
415
449
  # maximum_number_of_stories
@@ -429,7 +463,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
429
463
 
430
464
  # footprint_area
431
465
  if building.standardsBuildingType.is_initialized
432
- if not ['Residential'].include?(building.standardsBuildingType.get)
466
+ if !['Residential'].include?(building.standardsBuildingType.get)
433
467
  feature_report.program.footprint_area_sqft = feature_report.program.floor_area_sqft / number_of_stories
434
468
  else
435
469
  feature_report.program.footprint_area_sqft = convert_units(floor_area, 'm^2', 'ft^2') / building.additionalProperties.getFeatureAsInteger('NumberOfConditionedStories').get
@@ -459,6 +493,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
459
493
  building_type = building_type.get
460
494
  end
461
495
  next if ['Residential'].include?(building_type) # space types with empty building type fields will inherit from the building object
496
+
462
497
  space_type_areas[building_type] = 0 if space_type_areas[building_type].nil?
463
498
  space_type_areas[building_type] += convert_units(space_type.floorArea, 'm^2', 'ft^2')
464
499
  end
@@ -471,6 +506,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
471
506
  else
472
507
  building_type = space.spaceType.get.standardsBuildingType
473
508
  end
509
+
474
510
  if building_type.empty?
475
511
  building_type = 'unknown'
476
512
  else
@@ -689,15 +725,15 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
689
725
  # district_cooling
690
726
  district_cooling = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='District Cooling'")
691
727
  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)
728
+ if building.standardsBuildingType.is_initialized && ['Residential'].include?(building.standardsBuildingType.get)
729
+ feature_report.reporting_periods[0].district_cooling_kwh = 0.0
694
730
  end
695
731
 
696
732
  # district_heating
697
733
  district_heating = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='Total End Uses' AND ColumnName='District Heating'")
698
734
  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)
735
+ if building.standardsBuildingType.is_initialized && ['Residential'].include?(building.standardsBuildingType.get)
736
+ feature_report.reporting_periods[0].district_heating_kwh = 0.0
701
737
  end
702
738
 
703
739
  # water
@@ -725,10 +761,10 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
725
761
  # report each query in its corresponding feature report obeject
726
762
  x = ft.tr(' ', '_').downcase
727
763
  if x.include? 'water'
728
- x_u = x + '_qbft'
729
- else
764
+ x_u = "#{x}_qbft"
765
+ else
730
766
  x = x.gsub('_#2', '')
731
- x_u = x + '_kwh'
767
+ x_u = "#{x}_kwh"
732
768
  end
733
769
  m = feature_report.reporting_periods[0].end_uses.send(x_u)
734
770
 
@@ -739,8 +775,8 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
739
775
  end
740
776
  sql_r = convert_units(sql_r, 'GJ', 'kWh')
741
777
 
742
- if building.standardsBuildingType.is_initialized
743
- sql_r = 0.0 if ['Residential'].include?(building.standardsBuildingType.get) && x_u.include?('district')
778
+ if building.standardsBuildingType.is_initialized && (['Residential'].include?(building.standardsBuildingType.get) && x_u.include?('district'))
779
+ sql_r = 0.0
744
780
  end
745
781
  m.send("#{y}=", sql_r)
746
782
  end
@@ -755,7 +791,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
755
791
  sql = sql_query(runner, sql_file, 'AnnualBuildingUtilityPerformanceSummary', "TableName='End Uses' AND RowName='#{eu}' AND ColumnName='#{ft}'")
756
792
 
757
793
  # ensure not nil so the equations below don't error out
758
- if not sql.nil?
794
+ if !sql.nil?
759
795
  sql_r += convert_units(sql, 'GJ', 'kWh')
760
796
  end
761
797
  end
@@ -798,24 +834,64 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
798
834
  time_setpoint_not_met_during_occupied_hours = time_setpoint_not_met_during_occupied_heating + time_setpoint_not_met_during_occupied_cooling
799
835
  feature_report.reporting_periods[0].comfort_result[:time_setpoint_not_met_during_occupied_hours] = time_setpoint_not_met_during_occupied_hours
800
836
 
801
- ######################################## Reporting TImeseries Results FOR CSV File ######################################
837
+ # electricity emissions
838
+ begin
802
839
 
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
840
+ # future_annual_emissions
841
+ future_annual_emissions_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Future_Annual_Electricity_Emissions', 'EMS')
842
+ feature_report.reporting_periods[0].emissions[:future_annual_electricity_emissions_mt] = future_annual_emissions_ts.get.values.sum
813
843
 
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
844
+ # future_hourly_emissions
845
+ future_hourly_emissions_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Future_Hourly_Electricity_Emissions', 'EMS')
846
+ feature_report.reporting_periods[0].emissions[:future_hourly_electricity_emissions_mt] = future_hourly_emissions_ts.get.values.sum
847
+
848
+ # historical_annual_emissions
849
+ historical_annual_emissions_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Historical_Annual_Electricity_Emissions', 'EMS')
850
+ feature_report.reporting_periods[0].emissions[:historical_annual_electricity_emissions_mt] = historical_annual_emissions_ts.get.values.sum
851
+
852
+ # historical_hourly_emissions
853
+ historical_hourly_emissions_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Historical_Hourly_Electricity_Emissions', 'EMS')
854
+ feature_report.reporting_periods[0].emissions[:historical_hourly_electricity_emissions_mt] = historical_hourly_emissions_ts.get.values.sum
855
+
856
+ # future_annual_emissions_intensity
857
+ future_annual_emissions_intensity_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Future_Annual_Electricity_Emissions_Intensity', 'EMS')
858
+ feature_report.reporting_periods[0].emissions[:future_annual_electricity_emissions_intensity_kg_per_ft2] = future_annual_emissions_intensity_ts.get.values.sum
859
+
860
+ # future_hourly_emissions_intensity
861
+ future_hourly_emissions_intensity_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Future_Hourly_Electricity_Emissions_Intensity', 'EMS')
862
+ feature_report.reporting_periods[0].emissions[:future_hourly_electricity_emissions_intensity_kg_per_ft2] = future_hourly_emissions_intensity_ts.get.values.sum
863
+
864
+ # historical_annual_emissions_intensity
865
+ historical_annual_emissions_intensity_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Historical_Annual_Electricity_Emissions_Intensity', 'EMS')
866
+ feature_report.reporting_periods[0].emissions[:historical_annual_electricity_emissions_intensity_kg_per_ft2] = historical_annual_emissions_intensity_ts.get.values.sum
867
+
868
+ # historical_hourly_emissions_intensity
869
+ historical_hourly_emissions_intensity_ts = sql_file.timeSeries(ann_env_pd.to_s, reporting_frequency.to_s, 'Historical_Hourly_Electricity_Emissions_Intensity', 'EMS')
870
+ feature_report.reporting_periods[0].emissions[:historical_hourly_electricity_emissions_intensity_kg_per_ft2] = historical_hourly_emissions_intensity_ts.get.values.sum
871
+
872
+ rescue StandardError
873
+ @@logger.info('Emissions are not reported for this feature')
817
874
  end
818
875
 
876
+ ##########################################################################################################################
877
+ # set conversion variables
878
+ conv_J_mwh = 1000000 * 60 * 60 # J to MWh (1000000J/MJ * 60hr/min * 60 min/sec)
879
+ conv_kg_mt = 0.001 # kg to metric ton
880
+ conv_kbtu_J = 1054852.32 # KBtu to J (1kBtu = 1054852.32 J)
881
+
882
+ ##### Emisison factors for natural gas, propane, and fuel oil based on EPA eGRID data and calculated using 20-year GWP horizon based on ASHRAE 189.1
883
+ ## natural gas : 277.358126 KG/MWH
884
+ ## propane : 323.896704 KG/MWH
885
+ ## Fuel oil : 294.962046 KG/MWH
886
+ nat_gas_val = 277.358126
887
+ lpg_val = 323.896704
888
+ fo1_val = 294.962046
889
+ fo2_val = 294.962046
890
+
891
+
892
+ ##########################################################################################################################
893
+ ######################################## Reporting TImeseries Results FOR CSV File #######################################
894
+
819
895
  # timeseries we want to report
820
896
  requested_timeseries_names = [
821
897
  'Electricity:Facility',
@@ -861,7 +937,31 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
861
937
  'District Heating Inlet Temperature',
862
938
  'District Heating Outlet Temperature',
863
939
  'Cooling Coil Total Cooling Rate',
864
- 'Heating Coil Heating Rate'
940
+ 'Heating Coil Heating Rate',
941
+ 'Future_Annual_Electricity_Emissions',
942
+ 'Future_Hourly_Electricity_Emissions',
943
+ 'Historical_Annual_Electricity_Emissions',
944
+ 'Historical_Hourly_Electricity_Emissions',
945
+ 'Future_Annual_Electricity_Emissions_Intensity',
946
+ 'Future_Hourly_Electricity_Emissions_Intensity',
947
+ 'Historical_Annual_Electricity_Emissions_Intensity',
948
+ 'Historical_Hourly_Electricity_Emissions_Intensity',
949
+ 'Natural_Gas_Emissions',
950
+ 'Natural_Gas_Emissions_Intensity',
951
+ 'Propane_Emissions',
952
+ 'Propane_Emissions_Intensity',
953
+ 'FuelOilNo2_Emissions',
954
+ 'FuelOilNo2_Emissions_Intensity',
955
+ 'Curtailed EV Power',
956
+ 'Daily EV Charge Energy Capacity',
957
+ 'EV Charge Ratio',
958
+ 'Total Charged EV Energy',
959
+ 'Total Curtailed EV Energy',
960
+ 'Total Scheduled EV Energy',
961
+ 'Emission Intensity Schedule Output',
962
+ 'EV Charging Effective Schedule',
963
+ 'EV Charging Original Schedule',
964
+ 'EV Charging Original Load'
865
965
  ]
866
966
 
867
967
  # add thermal comfort timeseries
@@ -880,7 +980,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
880
980
  runner.registerInfo("All timeseries: #{requested_timeseries_names}")
881
981
 
882
982
  # timeseries variables to keep to calculate power
883
- tsToKeep = ['Electricity:Facility', 'ElectricityProduced:Facility']
983
+ tsToKeep = ['Electricity:Facility', 'ElectricityProduced:Facility','Propane:Facility', 'NaturalGas:Facility', 'FuelOilNo2:Facility', 'FuelOilNo1:Facility']
884
984
  tsToKeepIndexes = {}
885
985
 
886
986
  ### powerFactor ###
@@ -954,7 +1054,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
954
1054
  # use key_value name
955
1055
  # special case for Zone Thermal Comfort: use both timeseries_name and key_value
956
1056
  if timeseries_name.include? 'Zone Thermal Comfort'
957
- new_timeseries_name = timeseries_name + ' ' + key_value
1057
+ new_timeseries_name = "#{timeseries_name} #{key_value}"
958
1058
  else
959
1059
  new_timeseries_name = key_value
960
1060
  end
@@ -982,8 +1082,8 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
982
1082
  end
983
1083
 
984
1084
  # 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)
1085
+ if building.standardsBuildingType.is_initialized && (['DistrictCooling:Facility', 'DistrictHeating:Facility'].include?(timeseries_name) && ['Residential'].include?(building.standardsBuildingType.get))
1086
+ values[key_cnt] = Array.new(n, 0)
987
1087
  end
988
1088
 
989
1089
  # unit conversion
@@ -1001,7 +1101,13 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1001
1101
  'm3'
1002
1102
  when 'W'
1003
1103
  'W'
1004
- end
1104
+ when 'kg'
1105
+ 'kg'
1106
+ when 'MT'
1107
+ 'MT'
1108
+ when 'KG/FT2'
1109
+ 'KG/FT2'
1110
+ end
1005
1111
  end
1006
1112
 
1007
1113
  # loop through each value and apply unit conversion
@@ -1021,6 +1127,103 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1021
1127
  tsToKeepIndexes[timeseries_name] = key_cnt
1022
1128
  end
1023
1129
 
1130
+ ### add emissions for natural gas, propane and fuel oil
1131
+ # # set conversion variables
1132
+ # conv_J_mwh = 1000000 * 60 * 60 # J to MWh (1000000J/MJ * 60hr/min * 60 min/sec)
1133
+ # conv_kg_mt = 0.001 # kg to metric ton
1134
+ # conv_kbtu_J = 1054852.32 # KBtu to J (1kBtu = 1054852.32 J)
1135
+
1136
+ # ##### Emisison factors for natural gas, propane, and fuel oil based on EPA eGRID data and calculated using 20-year GWP horizon based on ASHRAE 189.1
1137
+ # ## natural gas : 277.358126 KG/MWH
1138
+ # ## propane : 323.896704 KG/MWH
1139
+ # ## Fuel oil : 294.962046 KG/MWH
1140
+ # nat_gas_val = 277.358126
1141
+ # lpg_val = 323.896704
1142
+ # fo1_val = 294.962046
1143
+ # fo2_val = 294.962046
1144
+
1145
+ if timeseries_name == 'Natural_Gas_Emissions'
1146
+ newVals = Array.new(n, 0)
1147
+ (0..n - 1).each do |j|
1148
+ newVals[j] = (nat_gas_val * (values[tsToKeepIndexes['NaturalGas:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f
1149
+ j += 1
1150
+ end
1151
+ new_unit = 'MT'
1152
+ values[key_cnt] = newVals
1153
+
1154
+ # add emissions sum to feature report
1155
+ feature_report.reporting_periods[0].emissions[:natural_gas_emissions_mt] = newVals.sum
1156
+ end
1157
+
1158
+ if timeseries_name == 'Propane_Emissions'
1159
+ newVals = Array.new(n, 0)
1160
+ (0..n - 1).each do |j|
1161
+ newVals[j] = (lpg_val * (values[tsToKeepIndexes['Propane:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f
1162
+ j += 1
1163
+ end
1164
+ new_unit = 'MT'
1165
+ values[key_cnt] = newVals
1166
+
1167
+ # add emissions sum to feature report
1168
+ feature_report.reporting_periods[0].emissions[:propane_emissions_mt] = newVals.sum
1169
+ end
1170
+
1171
+ if timeseries_name == 'FuelOilNo2_Emissions'
1172
+ newVals = Array.new(n, 0)
1173
+ (0..n - 1).each do |j|
1174
+ newVals[j] = (fo2_val * (values[tsToKeepIndexes['FuelOilNo2:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f
1175
+ j += 1
1176
+ end
1177
+ new_unit = 'MT'
1178
+ values[key_cnt] = newVals
1179
+
1180
+ # add emissions sum to feature report
1181
+ feature_report.reporting_periods[0].emissions[:fueloil_no2_emissions_mt] = newVals.sum
1182
+ end
1183
+
1184
+ ### calculate emissions intensity metric
1185
+ # get flr_area
1186
+ flr_area = building.floorArea * 10.764 #change from m2 to ft2
1187
+
1188
+ if timeseries_name == 'Natural_Gas_Emissions_Intensity'
1189
+ newVals = Array.new(n, 0)
1190
+ (0..n - 1).each do |j|
1191
+ newVals[j] = (((nat_gas_val * (values[tsToKeepIndexes['NaturalGas:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f ) * 1000 / flr_area) # unit: kg/ft2 - changed mt to kg
1192
+ j += 1
1193
+ end
1194
+ new_unit = 'KG/FT2'
1195
+ values[key_cnt] = newVals
1196
+
1197
+ # add emissions sum to feature report
1198
+ feature_report.reporting_periods[0].emissions[:natural_gas_emissions_intensity_kg_per_ft2] = newVals.sum
1199
+ end
1200
+
1201
+ if timeseries_name == 'Propane_Emissions_Intensity'
1202
+ newVals = Array.new(n, 0)
1203
+ (0..n - 1).each do |j|
1204
+ newVals[j] = (((lpg_val * (values[tsToKeepIndexes['Propane:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f ) * 1000 / flr_area) # unit: kg/ft2 - changed mt to kg
1205
+ j += 1
1206
+ end
1207
+ new_unit = 'KG/FT2'
1208
+ values[key_cnt] = newVals
1209
+
1210
+ # add emissions sum to feature report
1211
+ feature_report.reporting_periods[0].emissions[:propane_emissions_intensity_kg_per_ft2] = newVals.sum
1212
+ end
1213
+
1214
+ if timeseries_name == 'FuelOilNo2_Emissions_Intensity'
1215
+ newVals = Array.new(n, 0)
1216
+ (0..n - 1).each do |j|
1217
+ newVals[j] = (((fo2_val * (values[tsToKeepIndexes['FuelOilNo2:Facility']][j].to_f * conv_kbtu_J.to_f) / conv_J_mwh.to_f ) * conv_kg_mt.to_f ) * 1000 / flr_area) # unit: kg/ft2 - changed mt to kg
1218
+ j += 1
1219
+ end
1220
+ new_unit = 'KG/FT2'
1221
+ values[key_cnt] = newVals
1222
+
1223
+ # add emissions sum to feature report
1224
+ feature_report.reporting_periods[0].emissions[:fueloil_no2_emissions_intensity_kg_per_ft2] = newVals.sum
1225
+ end
1226
+
1024
1227
  # special processing: power
1025
1228
  if powerTimeseries.include? timeseries_name
1026
1229
  # special case: net series (subtract generation from load)
@@ -1077,7 +1280,8 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1077
1280
  end
1078
1281
  end
1079
1282
  end
1080
- end
1283
+ end
1284
+
1081
1285
 
1082
1286
  # append units to headers
1083
1287
  new_timeseries_name += "(#{new_unit})"
@@ -1210,6 +1414,8 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
1210
1414
  end
1211
1415
  end
1212
1416
 
1417
+ puts "values = #{values}"
1418
+
1213
1419
  # closing the sql file
1214
1420
  sql_file.close
1215
1421
 
@@ -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