urbanopt-cli 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -22,8 +22,8 @@
22
22
  "net_metering_limit_kw": 0,
23
23
  "interconnection_limit_kw": 100000000.0,
24
24
  "blended_monthly_demand_charges_us_dollars_per_kw": [10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
25
- "blended_monthly_rates_us_dollars_per_kwh": [0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
26
- },
25
+ "blended_monthly_rates_us_dollars_per_kwh": [0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13, 0.13]
26
+ },
27
27
  "Wind": {
28
28
  "min_kw": 0,
29
29
  "max_kw": 0,
@@ -77,7 +77,7 @@
77
77
  "losses": 0.14,
78
78
  "array_type": 1,
79
79
  "module_type": 0,
80
- "gcr": 0.4,
80
+ "gcr": 1,
81
81
  "dc_ac_ratio": 1.2,
82
82
  "inv_eff": 0.96,
83
83
  "radius": 0,
@@ -77,7 +77,7 @@
77
77
  "losses": 0.14,
78
78
  "array_type": 1,
79
79
  "module_type": 0,
80
- "gcr": 0.4,
80
+ "gcr": 1,
81
81
  "dc_ac_ratio": 1.2,
82
82
  "inv_eff": 0.96,
83
83
  "radius": 0,
@@ -113,7 +113,7 @@
113
113
  "losses": 0.14,
114
114
  "array_type": 0,
115
115
  "module_type": 0,
116
- "gcr": 0.4,
116
+ "gcr": 1,
117
117
  "dc_ac_ratio": 1.2,
118
118
  "inv_eff": 0.96,
119
119
  "radius": 0,
@@ -2,7 +2,7 @@
2
2
 
3
3
  source 'http://rubygems.org'
4
4
 
5
- gem 'nokogiri', '~> 1.10'
5
+ gem 'nokogiri', '~> 1.12'
6
6
  gem 'oga'
7
7
  gem 'schematron-nokogiri'
8
8
  gem 'rake'
@@ -4,27 +4,17 @@ GEM
4
4
  ansi (1.5.0)
5
5
  ast (2.4.2)
6
6
  builder (3.2.4)
7
- ci_reporter (2.0.0)
8
- builder (>= 2.1.2)
9
- ci_reporter_minitest (1.0.0)
10
- ci_reporter (~> 2.0)
11
- minitest (~> 5.0)
12
- codecov (0.2.12)
13
- json
14
- simplecov
15
- docile (1.3.5)
16
- json (2.5.1)
17
- mini_portile2 (2.5.0)
7
+ mini_portile2 (2.6.1)
18
8
  minitest (5.14.4)
19
9
  minitest-reporters (1.4.3)
20
10
  ansi
21
11
  builder
22
12
  minitest (>= 5.0)
23
13
  ruby-progressbar
24
- nokogiri (1.11.2)
25
- mini_portile2 (~> 2.5.0)
14
+ nokogiri (1.12.5)
15
+ mini_portile2 (~> 2.6.1)
26
16
  racc (~> 1.4)
27
- nokogiri (1.11.2-x64-mingw32)
17
+ nokogiri (1.12.5-x64-mingw32)
28
18
  racc (~> 1.4)
29
19
  oga (3.3)
30
20
  ast
@@ -38,28 +28,19 @@ GEM
38
28
  ruby-progressbar (1.11.0)
39
29
  schematron-nokogiri (0.0.3)
40
30
  nokogiri (~> 1.6)
41
- simplecov (0.21.2)
42
- docile (~> 1.1)
43
- simplecov-html (~> 0.11)
44
- simplecov_json_formatter (~> 0.1)
45
- simplecov-html (0.12.3)
46
- simplecov_json_formatter (0.1.2)
47
31
 
48
32
  PLATFORMS
49
33
  ruby
50
34
  x64-mingw32
51
35
 
52
36
  DEPENDENCIES
53
- ci_reporter_minitest (~> 1.0.0)
54
- codecov (= 0.2.12)
55
37
  minitest (~> 5.9)
56
38
  minitest-reporters
57
- nokogiri (~> 1.10)
39
+ nokogiri (~> 1.12)
58
40
  oga
59
41
  parallel
60
42
  rake
61
43
  schematron-nokogiri
62
- simplecov
63
44
 
64
45
  BUNDLED WITH
65
- 2.2.11
46
+ 2.2.11
@@ -383,7 +383,7 @@
383
383
 
384
384
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
385
385
 
386
- var datasets = ['Electricity:Facility', 'ElectricityProduced:Facility', 'NaturalGas:Facility', 'Propane:Facility', 'FuelOilNo2:Facility', 'OtherFuels:Facility'];
386
+ var datasets = ['Electricity:Facility', 'REopt:ElectricityProduced:Total', 'NaturalGas:Facility', 'Propane:Facility', 'FuelOilNo2:Facility', 'OtherFuels:Facility'];
387
387
 
388
388
  var endUseKeys = ['Heating:Electricity', 'Cooling:Electricity', 'InteriorLights:Electricity', 'ExteriorLights:Electricity', 'ExteriorEquipment:Electricity', 'InteriorEquipment:Electricity', 'Fans:Electricity', 'Pumps:Electricity', 'HeatRejection:Electricity', 'WaterSystems:Electricity'];
389
389
 
@@ -483,7 +483,7 @@
483
483
  datasetUnit = 'Electricity:Facility(kWh)';
484
484
  }
485
485
  }
486
- } else if (dataset == 'ElectricityProduced:Facility') {
486
+ } else if (dataset == 'REopt:ElectricityProduced:Total') {
487
487
  // first check if there is data to include
488
488
  if (!(values.every(item => item === 0))) {
489
489
  if (changeToKbtu) {
@@ -543,13 +543,13 @@
543
543
  values: _.map(months, function (month, i) {
544
544
  var value = 0;
545
545
  if (changeToKbtu){
546
- value = feature.monthly_values['Electricity:Facility'][i]*3.41 - feature.monthly_values['ElectricityProduced:Facility'][i]*3.41;
546
+ value = feature.monthly_values['Electricity:Facility'][i]*3.41 - feature.monthly_values['REopt:ElectricityProduced:Total'][i]*3.41;
547
547
  _.forEach(kbtu_datasets, function(ds){
548
548
  value += feature.monthly_values[ds][i];
549
549
  });
550
550
  }
551
551
  else {
552
- value = feature.monthly_values['Electricity:Facility'][i] - feature.monthly_values['ElectricityProduced:Facility'][i]; //Values are in kWh
552
+ value = feature.monthly_values['Electricity:Facility'][i] - feature.monthly_values['REopt:ElectricityProduced:Total'][i]; //Values are in kWh
553
553
  }
554
554
 
555
555
  $scope.annualNetChartData[feature.name] += value;
@@ -373,7 +373,7 @@
373
373
 
374
374
  var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
375
375
 
376
- var datasets = ['Electricity:Facility', 'ElectricityProduced:Facility', 'NaturalGas:Facility', 'Propane:Facility', 'FuelOilNo2:Facility', 'OtherFuels:Facility'];
376
+ var datasets = ['Electricity:Facility', 'REopt:ElectricityProduced:Total', 'NaturalGas:Facility', 'Propane:Facility', 'FuelOilNo2:Facility', 'OtherFuels:Facility'];
377
377
 
378
378
  var endUseKeys = ['Heating:Electricity', 'Cooling:Electricity', 'InteriorLights:Electricity', 'ExteriorLights:Electricity', 'InteriorEquipment:Electricity', 'ExteriorEquipment:Electricity', 'Fans:Electricity', 'Pumps:Electricity', 'HeatRejection:Electricity', 'WaterSystems:Electricity'];
379
379
 
@@ -456,7 +456,7 @@
456
456
  datasetUnit = 'Electricity:Facility(kWh)';
457
457
  }
458
458
  }
459
- } else if (dataset == 'ElectricityProduced:Facility') {
459
+ } else if (dataset == 'REopt:ElectricityProduced:Total') {
460
460
  // first check if there is data to include
461
461
  if (!(values.every(item => item === 0))) {
462
462
  if (changeToKbtu) {
@@ -515,14 +515,14 @@
515
515
  values: _.map(months, function (month, i) {
516
516
  var value = 0;
517
517
  if (changeToKbtu){
518
- value = scenario.monthly_values['Electricity:Facility'][i]*3.41 - scenario.monthly_values['ElectricityProduced:Facility'][i]*3.41 + scenario.monthly_values['NaturalGas:Facility'][i]; //Values are in kBtu
518
+ value = scenario.monthly_values['Electricity:Facility'][i]*3.41 - scenario.monthly_values['REopt:ElectricityProduced:Total'][i]*3.41 + scenario.monthly_values['NaturalGas:Facility'][i]; //Values are in kBtu
519
519
 
520
520
  _.forEach(kbtu_datasets, function(ds){
521
521
  value += scenario.monthly_values[ds][i];
522
522
  });
523
523
  }
524
524
  else {
525
- value = scenario.monthly_values['Electricity:Facility'][i] - scenario.monthly_values['ElectricityProduced:Facility'][i]; //Values are in kWh
525
+ value = scenario.monthly_values['Electricity:Facility'][i] - scenario.monthly_values['REopt:ElectricityProduced:Total'][i]; //Values are in kWh
526
526
  }
527
527
  // value;
528
528
  $scope.annualNetChartData[scenario.name] += value;
@@ -40,6 +40,6 @@
40
40
 
41
41
  module URBANopt
42
42
  module CLI
43
- VERSION = '0.6.2'.freeze
43
+ VERSION = '0.6.3'.freeze
44
44
  end
45
45
  end
data/lib/uo_cli.rb CHANGED
@@ -129,6 +129,9 @@ module URBANopt
129
129
  opt :streets, "\nCreate default project wiht FeatureFile containing streets, used for RNM analysis\n" \
130
130
  "Example: uo create --project-folder urbanopt_example_project --streets", short: :t
131
131
 
132
+ opt :photovoltaic, "\nCreate default project with FeatureFile containing community photovoltaic for the district and ground-mount photovoltaic associated with buildings, used for REopt analysis \n" \
133
+ "Example: uo create --project-folder urbanopt_example_project --photovoltaic", short: :v
134
+
132
135
  opt :empty, "\nUse with --project-folder argument to create an empty project folder\n" \
133
136
  "Then add your own Feature file in the project directory you created,\n" \
134
137
  "add Weather files in the weather folder and add OpenStudio models of Features\n" \
@@ -226,10 +229,10 @@ module URBANopt
226
229
  "Example: uo rnm --scenario baseline_scenario.csv --feature example_project.json --reopt", short: :r
227
230
 
228
231
  opt :extended_catalog, "\nUse this option to specify the extended electrical catalog path.\n" \
229
- "If this option is not included, the default catalog will be used", short: :c
232
+ "If this option is not included, the default catalog will be used", type: String, short: :c
230
233
 
231
234
  opt :average_peak_catalog, "\nUse this option to specify the average peak catalog path.\n" \
232
- "If this option is not included, the default catalog will be used", short: :a
235
+ "If this option is not included, the default catalog will be used", type: String, short: :a
233
236
 
234
237
  opt :opendss, "\n If this option is specified, an OpenDSS-compatible electrical database will be created \n" \
235
238
  "Example: uo rnm --scenario baseline_scenario.csv --feature example_project_with_streets.json --opendss", short: :o
@@ -533,11 +536,13 @@ module URBANopt
533
536
  FileUtils.cp(File.join(path_item, 'example_project_with_electric_network.json'), dir_name)
534
537
  elsif @opthash.subopts[:streets] == true
535
538
  FileUtils.cp(File.join(path_item, 'example_project_with_streets.json'), dir_name)
539
+ elsif @opthash.subopts[:photovoltaic] == true
540
+ FileUtils.cp(File.join(path_item, 'example_project_with_PV.json'), dir_name)
536
541
  end
537
542
 
538
543
  if @opthash.subopts[:floorspace] == false
539
544
 
540
- if @opthash.subopts[:electric] != true && @opthash.subopts[:streets] != true
545
+ if @opthash.subopts[:electric] != true && @opthash.subopts[:streets] != true && @opthash.subopts[:photovoltaic] != true
541
546
  # copy feature file
542
547
  FileUtils.cp(File.join(path_item, 'example_project.json'), dir_name)
543
548
  end
@@ -554,6 +559,7 @@ module URBANopt
554
559
  FileUtils.cp(File.join(path_item, 'mappers/HighEfficiency.rb'), File.join(dir_name, 'mappers'))
555
560
  FileUtils.cp(File.join(path_item, 'mappers/ThermalStorage.rb'), File.join(dir_name, 'mappers'))
556
561
  FileUtils.cp(File.join(path_item, 'mappers/EvCharging.rb'), File.join(dir_name, 'mappers'))
562
+ FileUtils.cp(File.join(path_item, 'mappers/FlexibleHotWater.rb'), File.join(dir_name, 'mappers'))
557
563
 
558
564
  # copy osw file
559
565
  FileUtils.cp(File.join(path_item, 'mappers/base_workflow.osw'), File.join(dir_name, 'mappers'))
@@ -923,29 +929,57 @@ module URBANopt
923
929
  scenario_assumptions = File.expand_path(@opthash.subopts[:reopt_scenario_assumptions_file]).to_s
924
930
  end
925
931
  puts "\nRunning the REopt Scenario post-processor with scenario assumptions file: #{scenario_assumptions}\n"
932
+ # Add community photovoltaic if present in the Feature File
933
+ community_photovoltaic = []
934
+ feature_file = JSON.parse(File.read(File.expand_path(@opthash.subopts[:feature])), symbolize_names: true)
935
+ feature_file[:features].each do |feature|
936
+ begin
937
+ if feature[:properties][:district_system_type]
938
+ if feature[:properties][:district_system_type] == 'Community Photovoltaic'
939
+ community_photovoltaic << feature
940
+ end
941
+ end
942
+ rescue
943
+ end
944
+ end
926
945
  reopt_post_processor = URBANopt::REopt::REoptPostProcessor.new(
927
946
  scenario_report,
928
947
  scenario_assumptions,
929
948
  scenario_base.reopt_feature_assumptions,
930
- DEVELOPER_NREL_KEY
949
+ DEVELOPER_NREL_KEY,false
931
950
  )
932
951
  if @opthash.subopts[:reopt_scenario] == true
933
952
  puts "\nPost-processing entire scenario with REopt\n"
934
953
  scenario_report_scenario = reopt_post_processor.run_scenario_report(
935
954
  scenario_report: scenario_report,
936
955
  save_name: 'scenario_optimization',
937
- run_resilience: @opthash.subopts[:reopt_resilience]
956
+ run_resilience: @opthash.subopts[:reopt_resilience],
957
+ community_photovoltaic: community_photovoltaic
938
958
  )
939
959
  results << { "process_type": 'reopt_scenario', "status": 'Complete', "timestamp": Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
940
960
  puts "\nDone\n"
941
961
  elsif @opthash.subopts[:reopt_feature] == true
942
962
  puts "\nPost-processing each building individually with REopt\n"
963
+ # Add groundmount photovoltaic if present in the Feature File
964
+ groundmount_photovoltaic = {}
965
+ feature_file = JSON.parse(File.read(File.expand_path(@opthash.subopts[:feature])), symbolize_names: true)
966
+ feature_file[:features].each do |feature|
967
+ begin
968
+ if feature[:properties][:district_system_type]
969
+ if feature[:properties][:district_system_type] == 'Ground Mount Photovoltaic'
970
+ groundmount_photovoltaic[feature[:properties][:associated_building_id]] = feature[:properties][:footprint_area]
971
+ end
972
+ end
973
+ rescue
974
+ end
975
+ end
943
976
  scenario_report_features = reopt_post_processor.run_scenario_report_features(
944
977
  scenario_report: scenario_report,
945
978
  save_names_feature_reports: ['feature_optimization'] * scenario_report.feature_reports.length,
946
979
  save_name_scenario_report: 'feature_optimization',
947
980
  run_resilience: @opthash.subopts[:reopt_resilience],
948
- keep_existing_output: @opthash.subopts[:reopt_keep_existing]
981
+ keep_existing_output: @opthash.subopts[:reopt_keep_existing],
982
+ groundmount_photovoltaic: groundmount_photovoltaic
949
983
  )
950
984
  results << { "process_type": 'reopt_feature', "status": 'Complete', "timestamp": Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
951
985
  puts "\nDone\n"
@@ -971,11 +1005,16 @@ module URBANopt
971
1005
  scenario_folders = []
972
1006
  scenario_report_exists = false
973
1007
  Dir.glob(File.join(run_dir, '/*_scenario')) do |scenario_folder|
974
- scenario_report = File.join(scenario_folder, 'default_scenario_report.csv')
975
- if File.exist?(scenario_report)
976
- scenario_folders << scenario_folder
1008
+ scenario_report = File.join(scenario_folder, 'scenario_optimization.csv')
1009
+ # Check if Scenario Optimization REopt file exists and add that
1010
+ if File.exist?(File.join(scenario_folder, 'scenario_optimization.csv'))
1011
+ scenario_folders << File.join(scenario_folder, 'scenario_optimization.csv')
977
1012
  scenario_report_exists = true
978
- else
1013
+ # Check if Default Feature Report exists and add that
1014
+ elsif File.exist?(File.join(scenario_folder, 'default_scenario_report.csv'))
1015
+ scenario_folders << File.join(scenario_folder, 'default_scenario_report.csv')
1016
+ scenario_report_exists = true
1017
+ elsif
979
1018
  puts "\nERROR: Default reports not created for #{scenario_folder}. Please use 'process --default' to create default post processing reports for all scenarios first. Visualization not generated for #{scenario_folder}.\n"
980
1019
  end
981
1020
  end
@@ -1011,11 +1050,14 @@ module URBANopt
1011
1050
  feature_folders = []
1012
1051
  # loop through building feature ids from scenario csv
1013
1052
  csv['Feature Id'].each do |feature|
1014
- feature_report = File.join(run_dir, feature, 'feature_reports')
1015
- if File.exist?(feature_report)
1053
+ # Check if Feature Optimization REopt file exists and add that
1054
+ if File.exist?(File.join(run_dir, feature, 'feature_reports/feature_optimization.csv'))
1016
1055
  feature_report_exists = true
1017
- feature_folders << File.join(run_dir, feature)
1018
- else
1056
+ feature_folders << File.join(run_dir, feature, 'feature_reports/feature_optimization.csv')
1057
+ elsif File.exist?(File.join(run_dir, feature, 'feature_reports/default_feature_report.csv'))
1058
+ feature_report_exists = true
1059
+ feature_folders << File.join(run_dir, feature, 'feature_reports/default_feature_report.csv')
1060
+ elsif
1019
1061
  puts "\nERROR: Default reports not created for #{feature}. Please use 'process --default' to create default post processing reports for all features first. Visualization not generated for #{feature}.\n"
1020
1062
  end
1021
1063
  end
data/uo_cli.gemspec CHANGED
@@ -34,11 +34,11 @@ Gem::Specification.new do |spec|
34
34
 
35
35
  # use specific versions of urbanopt and openstudio dependencies while under heavy development
36
36
  spec.add_runtime_dependency 'optimist', '~> 3'
37
- spec.add_runtime_dependency 'urbanopt-geojson', '~> 0.6.5'
38
- spec.add_runtime_dependency 'urbanopt-reporting', '~> 0.4.1'
39
- spec.add_runtime_dependency 'urbanopt-scenario', '~> 0.6.2'
40
- spec.add_runtime_dependency 'urbanopt-reopt', '~> 0.6.1'
41
- spec.add_runtime_dependency 'urbanopt-rnm-us', '~> 0.1.0'
37
+ spec.add_runtime_dependency 'urbanopt-geojson', '~> 0.6.6'
38
+ spec.add_runtime_dependency 'urbanopt-reporting', '~> 0.4.2'
39
+ spec.add_runtime_dependency 'urbanopt-scenario', '~> 0.6.3'
40
+ spec.add_runtime_dependency 'urbanopt-reopt', '~> 0.6.2'
41
+ spec.add_runtime_dependency 'urbanopt-rnm-us', '~> 0.1.1'
42
42
 
43
43
  spec.add_development_dependency 'bundler', '>= 2.1.0'
44
44
  spec.add_development_dependency 'rake', '~> 13.0'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: urbanopt-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Moore
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-07-23 00:00:00.000000000 Z
11
+ date: 2021-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: optimist
@@ -30,70 +30,70 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.6.5
33
+ version: 0.6.6
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.6.5
40
+ version: 0.6.6
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: urbanopt-reporting
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.4.1
47
+ version: 0.4.2
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.4.1
54
+ version: 0.4.2
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: urbanopt-scenario
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.6.2
61
+ version: 0.6.3
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.6.2
68
+ version: 0.6.3
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: urbanopt-reopt
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 0.6.1
75
+ version: 0.6.2
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 0.6.1
82
+ version: 0.6.2
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: urbanopt-rnm-us
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: 0.1.0
89
+ version: 0.1.1
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: 0.1.0
96
+ version: 0.1.1
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: bundler
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -209,11 +209,13 @@ files:
209
209
  - example_files/example_floorspace_project.json
210
210
  - example_files/example_project.json
211
211
  - example_files/example_project_combined.json
212
+ - example_files/example_project_with_PV.json
212
213
  - example_files/example_project_with_electric_network.json
213
214
  - example_files/example_project_with_streets.json
214
215
  - example_files/mappers/Baseline.rb
215
216
  - example_files/mappers/CreateBar.rb
216
217
  - example_files/mappers/EvCharging.rb
218
+ - example_files/mappers/FlexibleHotWater.rb
217
219
  - example_files/mappers/Floorspace.rb
218
220
  - example_files/mappers/HighEfficiency.rb
219
221
  - example_files/mappers/HighEfficiencyCreateBar.rb