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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -1
- data/LICENSE.md +17 -17
- data/doc_templates/LICENSE.md +17 -17
- data/doc_templates/copyright_erb.txt +2 -2
- data/doc_templates/copyright_js.txt +2 -2
- data/doc_templates/copyright_ruby.txt +1 -1
- data/docs/package-lock.json +15717 -1407
- data/lib/measures/.rubocop.yml +4 -2
- data/lib/measures/default_feature_reports/measure.rb +101 -36
- data/lib/measures/export_modelica_loads/measure.rb +2 -1
- data/lib/measures/export_time_series_modelica/measure.rb +58 -59
- data/lib/measures/export_time_series_modelica/resources/os_lib_helper_methods.rb +3 -5
- data/lib/urbanopt/reporting/default_reports/construction_cost.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/date.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/distributed_generation.rb +25 -7
- data/lib/urbanopt/reporting/default_reports/end_use.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/end_uses.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/extension.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/feature_report.rb +9 -8
- data/lib/urbanopt/reporting/default_reports/generator.rb +1 -2
- data/lib/urbanopt/reporting/default_reports/location.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/logger.rb +2 -2
- data/lib/urbanopt/reporting/default_reports/power_distribution.rb +22 -6
- data/lib/urbanopt/reporting/default_reports/program.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/reporting_period.rb +30 -7
- data/lib/urbanopt/reporting/default_reports/scenario_power_distribution.rb +148 -0
- data/lib/urbanopt/reporting/default_reports/scenario_report.rb +20 -14
- data/lib/urbanopt/reporting/default_reports/schema/scenario_csv_columns.txt +18 -0
- data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +240 -6
- data/lib/urbanopt/reporting/default_reports/solar_pv.rb +42 -3
- data/lib/urbanopt/reporting/default_reports/storage.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/thermal_storage.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/timeseries_csv.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/validator.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/wind.rb +11 -2
- data/lib/urbanopt/reporting/default_reports.rb +1 -1
- data/lib/urbanopt/reporting/derived_extension.rb +1 -1
- data/lib/urbanopt/reporting/version.rb +2 -2
- data/lib/urbanopt/reporting.rb +1 -1
- data/urbanopt-reporting-gem.gemspec +3 -4
- metadata +16 -15
data/lib/measures/.rubocop.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt™, Copyright (c) 2019-
|
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(
|
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
|
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
|
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
|
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
|
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
|
729
|
-
else
|
749
|
+
x_u = "#{x}_qbft"
|
750
|
+
else
|
730
751
|
x = x.gsub('_#2', '')
|
731
|
-
x_u = x
|
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
|
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
|
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
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
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
|
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)
|
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
|
-
|
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-
|
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-
|
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__)
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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?
|
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
|
-
|
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
|
-
|
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
|
-
|
209
|
-
while
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
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
|
-
|
295
|
+
case arg
|
296
|
+
when 'hhw_loop_name'
|
296
297
|
args[arg] = new_val.to_s
|
297
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
379
|
-
|
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(
|
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(
|
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
|
-
|
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-
|
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
|
-
|
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-
|
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-
|
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+
|