urbanopt-cli 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d1403126b59a00ca08656510c8f97147cf88dc7b58be19d63944f99120c27d73
4
- data.tar.gz: c5502d2e07c64a04908e4939ad83d7c312a790b06e0842dd053809263b05ab06
3
+ metadata.gz: 3b8ee2cd09a50121cae55adfc77ef76ea468e1923eb6bfde899e35b193261dd4
4
+ data.tar.gz: '08b77907722db1cbc4465a8864735545dfe55b8f9820e7da1e93b1348bd3e860'
5
5
  SHA512:
6
- metadata.gz: 6f4482a92fc524b4d104764f9a654b62a2aeda1c78183c3f96a59e755645ba67b73b27ac667881f8bf436e8ad99f4ff5d1c8b3caaeed1b75a5b14bb9144f9443
7
- data.tar.gz: 6862733daffd4901ec5ab6dc0f23ad5957c566fb86faa8b10ca8f5b89745bee6b351d5f3a6a9a596f97570a5624d0fa575dfc3e2334603e9253d7198ee3f2986
6
+ metadata.gz: d078d451cc11e8eff4ea463a2bf5e40d3c28d8ae3551036de31f9c2a4432bd564b67ec03f1753fd64bf2a12ecd4eb088c71f15bd36508af91cdca9dd0e84a849
7
+ data.tar.gz: f3f2ceb4c12281606e52a5f9a2977cf4eab015dad74c9456cf75c89d655149638686ae8eb9c6778cb8c3e03750ebab2ee34d97d8d60883ae4351c950fe419a2b
@@ -0,0 +1,60 @@
1
+ name: nightly_build
2
+
3
+ on:
4
+ # push:
5
+ schedule:
6
+ # https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#schedule
7
+ # 5:24 am UTC (11:24pm MDT the day before) every weekday night in MDT
8
+ - cron: '24 5 * * 2-6'
9
+
10
+ env:
11
+ # Favor_Local_Gems enforces develop branch of all Ruby dependencies
12
+ # This is our canary in the coal mine! If any simulation tests fail, comment this and retry.
13
+ # If CI is then successful, we have a breaking change in a dependency somewhere.
14
+ FAVOR_LOCAL_GEMS: true
15
+ GEM_DEVELOPER_KEY: ${{ secrets.GEM_DEVELOPER_KEY }}
16
+ UO_NUM_PARALLEL: 2
17
+ # GHA machines only have 2 cores. Trying to run more than that is even slower.
18
+ # https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
19
+
20
+ jobs:
21
+ weeknight-tests:
22
+ # ubuntu-latest works since https://github.com/rbenv/ruby-build/releases/tag/v20220710 (July 10, 2022)
23
+ # https://github.com/rbenv/ruby-build/discussions/1940
24
+ runs-on: ubuntu-latest
25
+ container:
26
+ image: docker://nrel/openstudio:3.5.1
27
+ steps:
28
+ - uses: actions/checkout@v3
29
+ - name: Set up Python
30
+ uses: actions/setup-python@v4
31
+ with:
32
+ # Disco needs python 3.10
33
+ python-version: '3.10'
34
+ - name: Install Ruby dependencies
35
+ run: |
36
+ ruby --version
37
+ bundle update
38
+ bundle exec certified-update
39
+ - name: Install python dependencies
40
+ run: bundle exec uo install_python
41
+ - name: Run Rspec
42
+ continue-on-error: true
43
+ # Continue to upload step even if a test fails, so we can troubleshoot
44
+ run: bundle exec rspec
45
+ - name: Upload artifacts
46
+ # Save results for examination - useful for debugging
47
+ uses: actions/upload-artifact@v3
48
+ if: failure() # Only upload if rspec fails
49
+ with:
50
+ name: rspec_results
51
+ path: |
52
+ spec/test_directory**/run/
53
+ # coverage/
54
+ retention-days: 7 # save for 1 week before deleting
55
+ # coveralls action docs: https://github.com/marketplace/actions/coveralls-github-action
56
+ # - name: Coveralls
57
+ # uses: coverallsapp/github-action@1.1.3
58
+ # with:
59
+ # github-token: ${{ secrets.GITHUB_TOKEN }}
60
+ # path-to-lcov: "./coverage/lcov/urbanopt-cli.lcov"
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 0.9.2
4
+ Date Range: 01/06/23 - 04/11/23:
5
+
6
+ - Fixed [#417]( https://github.com/urbanopt/urbanopt-cli/pull/417 ), pin addressable dependency to resolve unicode_normalize error
7
+ - Fixed [#397]( https://github.com/urbanopt/urbanopt-cli/pull/397 ), New tests for GEB mappers
8
+
3
9
  ## Version 0.9.1
4
10
  Date Range: 12/14/22 - 01/05/23:
5
11
 
data/CMakeLists.txt CHANGED
@@ -1,7 +1,7 @@
1
1
  cmake_minimum_required(VERSION 3.10.2)
2
2
  cmake_policy(SET CMP0048 NEW)
3
3
 
4
- project(URBANoptCLI VERSION 0.8.3)
4
+ project(URBANoptCLI VERSION 0.9.1)
5
5
 
6
6
  include(FindOpenStudioSDK.cmake)
7
7
 
@@ -89,16 +89,16 @@ option(BUILD_PACKAGE "Build package" OFF)
89
89
  # need to update the MD5sum for each platform and url below
90
90
  if(UNIX)
91
91
  if(APPLE)
92
- set(URBANOPT_CLI_GEMS_ZIP_FILENAME "urbanopt-cli-gems-20221011-darwin.tar.gz")
93
- set(URBANOPT_CLI_GEMS_ZIP_EXPECTED_MD5 "9eee6fb77b168d1b2211e1888f733c63")
92
+ set(URBANOPT_CLI_GEMS_ZIP_FILENAME "urbanopt-cli-gems-20230111-darwin.tar.gz")
93
+ set(URBANOPT_CLI_GEMS_ZIP_EXPECTED_MD5 "dfb4d2d28d6ff25b42d8e375b4435be2")
94
94
  else()
95
- set(URBANOPT_CLI_GEMS_ZIP_FILENAME "urbanopt-cli-gems-20221011-linux.tar.gz")
96
- set(URBANOPT_CLI_GEMS_ZIP_EXPECTED_MD5 "5d10dc28cca00bbaed4df8ba0a930868")
95
+ set(URBANOPT_CLI_GEMS_ZIP_FILENAME "urbanopt-cli-gems-20230111-linux.tar.gz")
96
+ set(URBANOPT_CLI_GEMS_ZIP_EXPECTED_MD5 "2edb06d97ea496a3b3929a780404bb05")
97
97
  endif()
98
98
  elseif(WIN32)
99
99
  if(CMAKE_CL_64)
100
- set(URBANOPT_CLI_GEMS_ZIP_FILENAME "urbanopt-cli-gems-20221011-windows.tar.gz")
101
- set(URBANOPT_CLI_GEMS_ZIP_EXPECTED_MD5 "9c9dff191bc91379ce60923bfe6cfa4a")
100
+ set(URBANOPT_CLI_GEMS_ZIP_FILENAME "urbanopt-cli-gems-20230111-windows.tar.gz")
101
+ set(URBANOPT_CLI_GEMS_ZIP_EXPECTED_MD5 "ecbad071c3aba2223e9ad5803c8004d8")
102
102
  endif()
103
103
  endif()
104
104
 
@@ -211,7 +211,7 @@ elseif(UNIX)
211
211
  # set(CPACK_DEBIAN_PACKAGE_DEBUG ON)
212
212
 
213
213
  # These two will set the .deb install path correctly
214
- set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqdbm14,sqlite3,libgomp1")
214
+ set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqdbm14,sqlite3,libgomp1,libncurses5")
215
215
  set(CPACK_SET_DESTDIR ON)
216
216
  set(CPACK_INSTALL_PREFIX /usr/local/urbanopt-cli-${URBANOPT_CLI_VERSION})
217
217
 
@@ -1,6 +1,6 @@
1
1
  set(OPENSTUDIO_VERSION_MAJOR 3)
2
- set(OPENSTUDIO_VERSION_MINOR 4)
3
- set(OPENSTUDIO_VERSION_PATCH 0)
2
+ set(OPENSTUDIO_VERSION_MINOR 5)
3
+ set(OPENSTUDIO_VERSION_PATCH 1)
4
4
  set(OPENSTUDIO_VERSION "${OPENSTUDIO_VERSION_MAJOR}.${OPENSTUDIO_VERSION_MINOR}.${OPENSTUDIO_VERSION_PATCH}")
5
5
 
6
6
  find_package(openstudio "${OPENSTUDIO_VERSION}" CONFIG)
@@ -16,23 +16,23 @@ else()
16
16
  set(OPENSTUDIO_BASELINK "https://openstudio-builds.s3.amazonaws.com/${OPENSTUDIO_VERSION}"
17
17
  CACHE STRING "Base link to where the openstudio archives are hosted" FORCE)
18
18
 
19
- set(OPENSTUDIO_VERSION_SHA "+4bd816f785")
19
+ set(OPENSTUDIO_VERSION_SHA "+22e1db7be5")
20
20
 
21
21
  if(APPLE)
22
- set(OPENSTUDIO_EXPECTED_HASH 5a1e5fdfc61a879a9d72dcf625a83e65)
23
- set(OPENSTUDIO_PLATFORM "Darwin")
22
+ set(OPENSTUDIO_EXPECTED_HASH f21b03a44aa9ac3e52a4bdfa20009171)
23
+ set(OPENSTUDIO_PLATFORM "Darwin-x86_64")
24
24
  set(OPENSTUDIO_EXT "tar.gz")
25
25
  elseif(UNIX)
26
26
  if(LSB_RELEASE_VERSION_SHORT MATCHES "20.04")
27
- set(OPENSTUDIO_EXPECTED_HASH 1922de95bb3e196f1c719400ce58871c)
27
+ set(OPENSTUDIO_EXPECTED_HASH 6e5c93002f0cfb445dcdcdb1270261a4)
28
+ set(OPENSTUDIO_PLATFORM "Ubuntu-20.04")
29
+ else() # Assumes 20.04
30
+ set(OPENSTUDIO_EXPECTED_HASH 6e5c93002f0cfb445dcdcdb1270261a4)
28
31
  set(OPENSTUDIO_PLATFORM "Ubuntu-20.04")
29
- else() # Assumes 18.04
30
- set(OPENSTUDIO_EXPECTED_HASH 44a837fa96fe2ce1a883492a3a1cae09)
31
- set(OPENSTUDIO_PLATFORM "Ubuntu-18.04")
32
32
  endif()
33
33
  set(OPENSTUDIO_EXT "tar.gz")
34
34
  elseif(WIN32)
35
- set(OPENSTUDIO_EXPECTED_HASH 9adffb37a62721ec51a33ce97533e956)
35
+ set(OPENSTUDIO_EXPECTED_HASH bc83efcb140d20f8f9758559a58c4347)
36
36
  set(OPENSTUDIO_PLATFORM "Windows")
37
37
  set(OPENSTUDIO_EXT "tar.gz")
38
38
  endif()
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
+ [![Coverage Status](https://coveralls.io/repos/github/urbanopt/urbanopt-cli/badge.svg?branch=develop)](https://coveralls.io/github/urbanopt/urbanopt-cli?branch=develop)
2
+
1
3
  # URBANopt CLI
2
4
 
3
5
  This is the command line interface (CLI) for the URBANopt™ SDK.
4
6
 
5
- ## Installation (Using Ruby)
7
+ ## Installation (Using Ruby)
6
8
 
7
9
  2 ) Using ruby add this line to your application's Gemfile:
8
10
 
@@ -25,40 +27,40 @@ gem install urbanopt-cli
25
27
 
26
28
  ## Installation (Using Installer)
27
29
 
28
- The UrbanOpt installer is an alternate way to install the UrbanOpt CLI that also includes Ruby 2.5.x and OpenStudio SDK.
29
- Below are installation instructions for each platform.
30
+ The UrbanOpt installer is an alternate way to install the UrbanOpt CLI that also includes Ruby 2.5.x and OpenStudio SDK.
31
+ Below are installation instructions for each platform.
30
32
 
31
33
  ### Linux (Ubuntu 18.04)
32
34
 
33
- Download the [.deb package](https://docs.urbanopt.net/installation/linux.html#install-with-the-urbanopt-installer).
35
+ Download the [.deb package](https://docs.urbanopt.net/installation/linux.html#install-with-the-urbanopt-installer).
34
36
 
35
37
  ```terminal
36
- sudo apt update
38
+ sudo apt update
37
39
  sudo apt install ./UrbanOptCLI-0.3.1.b6f118d506-Linux.deb
38
40
  ```
39
41
 
40
- This will install to `/usr/local/` directory.
41
- e.g.
42
- `/usr/local/urbanopt-cli-0.3.1/`
42
+ This will install to `/usr/local/` directory.
43
+ e.g.
44
+ `/usr/local/urbanopt-cli-0.3.1/`
43
45
 
44
- To run the UrbanOpt CLI, first run the `setup-env.sh` script that generates environmental variables and stores these in `env_uo.sh` in your home directory.
46
+ To run the UrbanOpt CLI, first run the `setup-env.sh` script that generates environmental variables and stores these in `env_uo.sh` in your home directory.
45
47
 
46
48
  ```terminal
47
- /usr/local/urbanopt-cli-0.3.1/setup-env.sh
49
+ /usr/local/urbanopt-cli-0.3.1/setup-env.sh
48
50
  . ~/.env_uo.sh
49
51
  ```
50
52
 
51
53
  When launching new shell terminals run `. ~/.env_uo.sh` to setup the environment. 
52
54
 
53
- ### Mac OSX (>= 10.12)
55
+ ### Mac OSX (>= 10.12)
54
56
 
55
- Download the [.dmg package](https://docs.urbanopt.net/installation/mac.html#install-with-the-urbanopt-installer).
57
+ Download the [.dmg package](https://docs.urbanopt.net/installation/mac.html#install-with-the-urbanopt-installer).
56
58
 
57
- Use the GUI installer and choose a directory to install. Once installed, open a terminal and run the provided setup script.
58
- The `setup-env.sh` generates env variables and stores them in a file `.env_uo.sh` in your home directory.
59
+ Use the GUI installer and choose a directory to install. Once installed, open a terminal and run the provided setup script.
60
+ The `setup-env.sh` generates env variables and stores them in a file `.env_uo.sh` in your home directory.
59
61
 
60
- ```terminal
61
- /Applications/UrbanOptCLI_0.3.1/setup-env.sh
62
+ ```terminal
63
+ /Applications/UrbanOptCLI_0.3.1/setup-env.sh
62
64
  . ~/.env_uo.sh
63
65
  ```
64
66
 
@@ -66,26 +68,26 @@ When launching new shell terminals run `. ~/.env_uo.s` to setup the environment.
66
68
 
67
69
  ### Windows (64-bit Windows 7 – 10)
68
70
 
69
- Download the [.exe installer](https://docs.urbanopt.net/installation/windows.html#install-with-the-urbanopt-installer).
71
+ Download the [.exe installer](https://docs.urbanopt.net/installation/windows.html#install-with-the-urbanopt-installer).
70
72
 
71
73
  Use the GUI installer and choose a directory to install. Once installed, open a terminal (Powershell, Windows CMD and GitBash are supported) and run the provided setup script for that shell (below are the setup scripts for each respective shell environment).
72
74
 
73
75
 
74
76
  #### Bash (or GitBash for Windows)
75
77
  ```terminal
76
- c:/urbanopt-cli-0.3.1/setup-env.sh
77
- . ~/.env_uo.sh
78
+ c:/urbanopt-cli-0.3.1/setup-env.sh
79
+ . ~/.env_uo.sh
78
80
  ```
79
81
 
80
82
  #### Powershell
81
83
  ```terminal
82
- c:\urbanopt-cli-0.3.1\setup-env.ps1
83
- . ~\.env_uo.ps1
84
+ c:\urbanopt-cli-0.3.1\setup-env.ps1
85
+ . ~\.env_uo.ps1
84
86
  ```
85
87
  #### Windows Command Prompt
86
88
  ```terminal
87
- c:\urbanopt-cli-0.3.1\setup-env.bat
88
- %HOMEPATH%\.env_uo.bat
89
+ c:\urbanopt-cli-0.3.1\setup-env.bat
90
+ %HOMEPATH%\.env_uo.bat
89
91
  ```
90
92
 
91
93
  When launching new shell terminals run the correct environment config to setup the environment. 
@@ -25,6 +25,8 @@ allow_local = ENV['FAVOR_LOCAL_GEMS']
25
25
  # gem 'urbanopt-core', github: 'URBANopt/urbanopt-core-gem', branch: 'develop'
26
26
  # end
27
27
 
28
+ # pin this dependency to avoid unicode_normalize error
29
+ gem 'addressable', '2.8.1'
28
30
 
29
31
  if allow_local && File.exist?('../openstudio-common-measures-gem')
30
32
  gem 'openstudio-common-measures', path: '../../openstudio-common-measures-gem'
@@ -391,55 +391,55 @@ module URBANopt
391
391
  # Options are: AZNMc, CAMXc, ERCTc, FRCCc, MROEc, MROWc, NEWEc, NWPPc, NYSTc, RFCEc, RFCMc, RFCWc, RMPAc, SPNOc, SPSOc, SRMVc, SRMWc, SRSOc, SRTVc, and SRVCc
392
392
  # egrid subregions can map directly to zipcodes but not to states. Some state might include multiple egrid subregions. the default mapper prioritize the egrid subregion that is most common in the state (covers the biggest number of zipcodes)
393
393
  future_emissions_mapping_hash =
394
- { 'FL': 'FRCCc', # ['FRCCc', 'SRSOc']
395
- 'MS': 'SRMVc', # ['SRMVc', 'SRTVc']
396
- 'NE': 'MROWc', # ['MROWc', 'RMPAc']
397
- 'OR': 'NWPPc',
398
- 'CA': 'CAMXc', # ['CAMXc', 'NWPPc']
399
- 'VA': 'SRVCc', # ['SRVCc', 'RFCWc', 'RFCEc'],
400
- 'AR': 'SRMVc', # ['SRMVc', 'SPSOc']
401
- 'TX': 'ERCTc', # ['ERCTc', 'SRMVc', 'SPSOc', 'AZNMc']
402
- 'OH': 'RFCWc',
403
- 'UT': 'NWPPc',
404
- 'MT': 'NWPPc', # ['NWPPc', 'MROWc']
405
- 'TN': 'SRTVc',
406
- 'ID': 'NWPPc',
407
- 'WI': 'MROEc', # ['RFCWc', 'MROEc', 'MROWc']
408
- 'WV': 'RFCWc',
409
- 'NC': 'SRVCc',
410
- 'LA': 'SRMVc',
411
- 'IL': 'SRMWc', # ['RFCWc', 'SRMWc']
412
- 'OK': 'SPSOc',
413
- 'IA': 'MROWc',
414
- 'WA': 'NWPPc',
415
- 'SD': 'MROWc', # ['MROWc', 'RMPAc']
416
- 'MN': 'MROWc',
417
- 'KY': 'SRTVc', # ['SRTVc', 'RFCWc']
418
- 'MI': 'RFCMc', # ['RFCMc', 'MROEc']
419
- 'KS': 'SPNOc',
420
- 'NJ': 'RFCEc',
421
- 'NY': 'NYSTc',
422
- 'IN': 'RFCWc',
423
- 'VT': 'NEWEc',
424
- 'NM': 'AZNMc', # ['AZNMc', 'SPSOc']
425
- 'WY': 'RMPAc', # ['RMPAc', 'NWPPc']
426
- 'GA': 'SRSOc',
427
- 'MO': 'SRMWc', # ['SRMWc', 'SPNOc']
428
- 'DC': 'RFCEc',
429
- 'SC': 'SRVCc',
430
- 'PA': 'RFCEc', # ['RFCEc', 'RFCWc']
431
- 'CO': 'RMPAc',
432
- 'AZ': 'AZNMc',
433
- 'ME': 'NEWEc',
434
- 'AL': 'SRSOc',
435
- 'MD': 'RFCEc', # ['RFCEc', 'RFCWc']
436
- 'NH': 'NEWEc',
437
- 'MA': 'NEWEc',
438
- 'ND': 'MROWc',
439
- 'NV': 'NWPPc', # ['NWPPc', 'AZNMc']
440
- 'CT': 'NEWEc',
441
- 'DE': 'RFCEc',
442
- 'RI': 'NEWEc' }
394
+ { FL: 'FRCCc', # ['FRCCc', 'SRSOc']
395
+ MS: 'SRMVc', # ['SRMVc', 'SRTVc']
396
+ NE: 'MROWc', # ['MROWc', 'RMPAc']
397
+ OR: 'NWPPc',
398
+ CA: 'CAMXc', # ['CAMXc', 'NWPPc']
399
+ VA: 'SRVCc', # ['SRVCc', 'RFCWc', 'RFCEc'],
400
+ AR: 'SRMVc', # ['SRMVc', 'SPSOc']
401
+ TX: 'ERCTc', # ['ERCTc', 'SRMVc', 'SPSOc', 'AZNMc']
402
+ OH: 'RFCWc',
403
+ UT: 'NWPPc',
404
+ MT: 'NWPPc', # ['NWPPc', 'MROWc']
405
+ TN: 'SRTVc',
406
+ ID: 'NWPPc',
407
+ WI: 'MROEc', # ['RFCWc', 'MROEc', 'MROWc']
408
+ WV: 'RFCWc',
409
+ NC: 'SRVCc',
410
+ LA: 'SRMVc',
411
+ IL: 'SRMWc', # ['RFCWc', 'SRMWc']
412
+ OK: 'SPSOc',
413
+ IA: 'MROWc',
414
+ WA: 'NWPPc',
415
+ SD: 'MROWc', # ['MROWc', 'RMPAc']
416
+ MN: 'MROWc',
417
+ KY: 'SRTVc', # ['SRTVc', 'RFCWc']
418
+ MI: 'RFCMc', # ['RFCMc', 'MROEc']
419
+ KS: 'SPNOc',
420
+ NJ: 'RFCEc',
421
+ NY: 'NYSTc',
422
+ IN: 'RFCWc',
423
+ VT: 'NEWEc',
424
+ NM: 'AZNMc', # ['AZNMc', 'SPSOc']
425
+ WY: 'RMPAc', # ['RMPAc', 'NWPPc']
426
+ GA: 'SRSOc',
427
+ MO: 'SRMWc', # ['SRMWc', 'SPNOc']
428
+ DC: 'RFCEc',
429
+ SC: 'SRVCc',
430
+ PA: 'RFCEc', # ['RFCEc', 'RFCWc']
431
+ CO: 'RMPAc',
432
+ AZ: 'AZNMc',
433
+ ME: 'NEWEc',
434
+ AL: 'SRSOc',
435
+ MD: 'RFCEc', # ['RFCEc', 'RFCWc']
436
+ NH: 'NEWEc',
437
+ MA: 'NEWEc',
438
+ ND: 'MROWc',
439
+ NV: 'NWPPc', # ['NWPPc', 'AZNMc']
440
+ CT: 'NEWEc',
441
+ DE: 'RFCEc',
442
+ RI: 'NEWEc' }
443
443
 
444
444
  # get the state from weather file
445
445
  state = feature.weather_filename.split('_', -1)[1]
@@ -459,55 +459,55 @@ module URBANopt
459
459
  # Mapping is done using mapping tools from eGrid and AVERT (ZipCode for eGrid and fraction of state for AVERT).
460
460
  # Mapped based on the maps of each set of regions:
461
461
  hourly_historical_mapping_hash =
462
- { 'FL': 'Florida',
463
- 'MS': 'Midwest',
464
- 'NE': 'Midwest', # MRWO could be Midwest / Central
465
- 'OR': 'Northwest',
466
- 'CA': 'California',
467
- 'VA': 'Carolinas',
468
- 'AR': 'Midwest',
469
- 'TX': 'Texas',
470
- 'OH': 'Midwest', # RFCW could be Midwest / Mid Atlantic
471
- 'UT': 'Northwest',
472
- 'MT': 'Northwest',
473
- 'TN': 'Tennessee',
474
- 'ID': 'Northwest',
475
- 'WI': 'Midwest',
476
- 'WV': 'Midwest', # RFCW could be Midwest / Mid Atlantic
477
- 'NC': 'Carolinas',
478
- 'LA': 'Midwest',
479
- 'IL': 'Midwest',
480
- 'OK': 'Central',
481
- 'IA': 'Midwest', # MRWO could be Midwest / Central
482
- 'WA': 'Northwest',
483
- 'SD': 'Midwest', # MRWO could be Midwest / Central
484
- 'MN': 'Midwest', # MRWO could be Midwest / Central
485
- 'KY': 'Tennessee',
486
- 'MI': 'Midwest',
487
- 'KS': 'Central',
488
- 'NJ': 'Mid-Atlantic',
489
- 'NY': 'New York',
490
- 'IN': 'Midwest', # RFCW could be Midwest / Mid Atlantic
491
- 'VT': 'New England',
492
- 'NM': 'Southwest',
493
- 'WY': 'Rocky Mountains',
494
- 'GA': 'SRSO',
495
- 'MO': 'Midwest',
496
- 'DC': 'Mid-Atlantic',
497
- 'SC': 'Carolinas',
498
- 'PA': 'Mid-Atlantic',
499
- 'CO': 'Rocky Mountains',
500
- 'AZ': 'Southwest',
501
- 'ME': 'New England',
502
- 'AL': 'Southeast',
503
- 'MD': 'Mid-Atlantic',
504
- 'NH': 'New England',
505
- 'MA': 'New England',
506
- 'ND': 'Midwest', # MRWO could be Midwest / Central
507
- 'NV': 'Northwest',
508
- 'CT': 'New England',
509
- 'DE': 'Mid-Atlantic',
510
- 'RI': 'New England' }
462
+ { FL: 'Florida',
463
+ MS: 'Midwest',
464
+ NE: 'Midwest', # MRWO could be Midwest / Central
465
+ OR: 'Northwest',
466
+ CA: 'California',
467
+ VA: 'Carolinas',
468
+ AR: 'Midwest',
469
+ TX: 'Texas',
470
+ OH: 'Midwest', # RFCW could be Midwest / Mid Atlantic
471
+ UT: 'Northwest',
472
+ MT: 'Northwest',
473
+ TN: 'Tennessee',
474
+ ID: 'Northwest',
475
+ WI: 'Midwest',
476
+ WV: 'Midwest', # RFCW could be Midwest / Mid Atlantic
477
+ NC: 'Carolinas',
478
+ LA: 'Midwest',
479
+ IL: 'Midwest',
480
+ OK: 'Central',
481
+ IA: 'Midwest', # MRWO could be Midwest / Central
482
+ WA: 'Northwest',
483
+ SD: 'Midwest', # MRWO could be Midwest / Central
484
+ MN: 'Midwest', # MRWO could be Midwest / Central
485
+ KY: 'Tennessee',
486
+ MI: 'Midwest',
487
+ KS: 'Central',
488
+ NJ: 'Mid-Atlantic',
489
+ NY: 'New York',
490
+ IN: 'Midwest', # RFCW could be Midwest / Mid Atlantic
491
+ VT: 'New England',
492
+ NM: 'Southwest',
493
+ WY: 'Rocky Mountains',
494
+ GA: 'SRSO',
495
+ MO: 'Midwest',
496
+ DC: 'Mid-Atlantic',
497
+ SC: 'Carolinas',
498
+ PA: 'Mid-Atlantic',
499
+ CO: 'Rocky Mountains',
500
+ AZ: 'Southwest',
501
+ ME: 'New England',
502
+ AL: 'Southeast',
503
+ MD: 'Mid-Atlantic',
504
+ NH: 'New England',
505
+ MA: 'New England',
506
+ ND: 'Midwest', # MRWO could be Midwest / Central
507
+ NV: 'Northwest',
508
+ CT: 'New England',
509
+ DE: 'Mid-Atlantic',
510
+ RI: 'New England' }
511
511
 
512
512
  # get the state from weather file
513
513
  state = feature.weather_filename.split('_', -1)[1]
@@ -524,55 +524,55 @@ module URBANopt
524
524
  # Options are: AKGD, AKMS, AZNM, CAMX, ERCT, FRCC, HIMS, HIOA, MROE, MROW, NEWE, NWPP, NYCW, NYLI, NYUP, RFCE, RFCM, RFCW, RMPA, SPNO, SPSO, SRMV, SRMW, SRSO, SRTV, and SRVC
525
525
  # egrid subregions can map directly to zipcodes but not to states. Some state might include multiple egrid subregions. the default mapper prioritize the egrid subregion that is most common in the state (covers the biggest number of zipcodes)
526
526
  annual_historical_mapping_hash =
527
- { 'FL': 'FRCC',
528
- 'MS': 'SRMV',
529
- 'NE': 'MROW',
530
- 'OR': 'NWPP',
531
- 'CA': 'CAMX',
532
- 'VA': 'SRVC',
533
- 'AR': 'SRMV',
534
- 'TX': 'ERCT',
535
- 'OH': 'RFCW',
536
- 'UT': 'NWPP',
537
- 'MT': 'NWPP',
538
- 'TN': 'SRTV',
539
- 'ID': 'NWPP',
540
- 'WI': 'MROE',
541
- 'WV': 'RFCW',
542
- 'NC': 'SRVC',
543
- 'LA': 'SRMV',
544
- 'IL': 'SRMW',
545
- 'OK': 'SPSO',
546
- 'IA': 'MROW',
547
- 'WA': 'NWPP',
548
- 'SD': 'MROW',
549
- 'MN': 'MROW',
550
- 'KY': 'SRTV',
551
- 'MI': 'RFCM',
552
- 'KS': 'SPNO',
553
- 'NJ': 'RFCE',
554
- 'NY': 'NYCW',
555
- 'IN': 'RFCW',
556
- 'VT': 'NEWE',
557
- 'NM': 'AZNM',
558
- 'WY': 'RMPA',
559
- 'GA': 'SRSO',
560
- 'MO': 'SRMW',
561
- 'DC': 'RFCE',
562
- 'SC': 'SRVC',
563
- 'PA': 'RFCE',
564
- 'CO': 'RMPA',
565
- 'AZ': 'AZNM',
566
- 'ME': 'NEWE',
567
- 'AL': 'SRSO',
568
- 'MD': 'RFCE',
569
- 'NH': 'NEWE',
570
- 'MA': 'NEWE',
571
- 'ND': 'MROW',
572
- 'NV': 'NWPP',
573
- 'CT': 'NEWE',
574
- 'DE': 'RFCE',
575
- 'RI': 'NEWE' }
527
+ { FL: 'FRCC',
528
+ MS: 'SRMV',
529
+ NE: 'MROW',
530
+ OR: 'NWPP',
531
+ CA: 'CAMX',
532
+ VA: 'SRVC',
533
+ AR: 'SRMV',
534
+ TX: 'ERCT',
535
+ OH: 'RFCW',
536
+ UT: 'NWPP',
537
+ MT: 'NWPP',
538
+ TN: 'SRTV',
539
+ ID: 'NWPP',
540
+ WI: 'MROE',
541
+ WV: 'RFCW',
542
+ NC: 'SRVC',
543
+ LA: 'SRMV',
544
+ IL: 'SRMW',
545
+ OK: 'SPSO',
546
+ IA: 'MROW',
547
+ WA: 'NWPP',
548
+ SD: 'MROW',
549
+ MN: 'MROW',
550
+ KY: 'SRTV',
551
+ MI: 'RFCM',
552
+ KS: 'SPNO',
553
+ NJ: 'RFCE',
554
+ NY: 'NYCW',
555
+ IN: 'RFCW',
556
+ VT: 'NEWE',
557
+ NM: 'AZNM',
558
+ WY: 'RMPA',
559
+ GA: 'SRSO',
560
+ MO: 'SRMW',
561
+ DC: 'RFCE',
562
+ SC: 'SRVC',
563
+ PA: 'RFCE',
564
+ CO: 'RMPA',
565
+ AZ: 'AZNM',
566
+ ME: 'NEWE',
567
+ AL: 'SRSO',
568
+ MD: 'RFCE',
569
+ NH: 'NEWE',
570
+ MA: 'NEWE',
571
+ ND: 'MROW',
572
+ NV: 'NWPP',
573
+ CT: 'NEWE',
574
+ DE: 'RFCE',
575
+ RI: 'NEWE' }
576
576
  # get the state from weather file
577
577
  state = feature.weather_filename.split('_', -1)[1]
578
578
 
@@ -880,7 +880,7 @@ module URBANopt
880
880
  if !template.nil? && template.include?('Residential IECC')
881
881
 
882
882
  captures = template.match(/Residential IECC (?<iecc_year>\d+) - Customizable Template (?<t_month>\w+) (?<t_year>\d+)/)
883
- template_vals = Hash[captures.names.zip(captures.captures)]
883
+ template_vals = captures.names.zip(captures.captures).to_h
884
884
  template_vals = template_vals.transform_keys(&:to_sym)
885
885
 
886
886
  epw = File.join(File.dirname(__FILE__), '../weather', feature.weather_filename)
@@ -994,18 +994,18 @@ module URBANopt
994
994
  default_args.each do |arg_name, arg_default|
995
995
  next if arg_default.nil?
996
996
 
997
- if !args.key?(arg_name)
998
- args[arg_name] = arg_default
999
- else
997
+ if args.key?(arg_name)
1000
998
  if debug
1001
- if !arg_default.nil?
999
+ if arg_default.nil?
1000
+ puts "Setting #{arg_name} to '#{args[arg_name]}'."
1001
+ else
1002
1002
  if args[arg_name] != arg_default
1003
1003
  puts "Overriding #{arg_name} default '#{arg_default}' with '#{args[arg_name]}'."
1004
1004
  end
1005
- else
1006
- puts "Setting #{arg_name} to '#{args[arg_name]}'."
1007
1005
  end
1008
1006
  end
1007
+ else
1008
+ args[arg_name] = arg_default
1009
1009
  end
1010
1010
  end
1011
1011
 
@@ -46,7 +46,7 @@ module URBANopt
46
46
 
47
47
  feature = features[0]
48
48
  building_type = feature.building_type
49
-
49
+
50
50
  # Energy Efficiency Measures
51
51
 
52
52
  OpenStudio::Extension.set_measure_argument(osw, 'AddOverhangsByProjectionFactor', '__SKIP__', true)
@@ -96,8 +96,8 @@ module URBANopt
96
96
  OpenStudio::Extension.set_measure_argument(osw, 'add_hpwh', 'flex1', 'Float')
97
97
  OpenStudio::Extension.set_measure_argument(osw, 'add_hpwh', 'flex_hrs1', '08:01-20:00')
98
98
 
99
- OpenStudio::Extension.set_measure_argument(osw,'add_packaged_ice_storage', '__SKIP__', true)
100
- OpenStudio::Extension.set_measure_argument(osw,'add_packaged_ice_storage', 'ice_cap', 'AutoSize')
99
+ OpenStudio::Extension.set_measure_argument(osw, 'add_packaged_ice_storage', '__SKIP__', true)
100
+ OpenStudio::Extension.set_measure_argument(osw, 'add_packaged_ice_storage', 'ice_cap', 'AutoSize')
101
101
 
102
102
  OpenStudio::Extension.set_measure_argument(osw, 'ShiftScheduleByType', '__SKIP__', true)
103
103
  OpenStudio::Extension.set_measure_argument(osw, 'ShiftScheduleByType', 'shift_value', -2)
@@ -162,7 +162,9 @@ class BuildResidentialModel < OpenStudio::Measure::ModelMeasure
162
162
 
163
163
  measures = {}
164
164
  hpxml_path = File.expand_path("../#{unit['name']}.xml")
165
- if !unit.key?('hpxml_path')
165
+ if unit.key?('hpxml_path')
166
+ FileUtils.cp(File.expand_path(unit['hpxml_path']), hpxml_path)
167
+ else
166
168
 
167
169
  # BuildResidentialHPXML
168
170
  measure_subdir = 'BuildResidentialHPXML'
@@ -196,8 +198,6 @@ class BuildResidentialModel < OpenStudio::Measure::ModelMeasure
196
198
  measure_args.delete('geometry_num_floors_above_grade')
197
199
 
198
200
  measures[measure_subdir] << measure_args
199
- else
200
- FileUtils.cp(File.expand_path(unit['hpxml_path']), hpxml_path)
201
201
  end
202
202
 
203
203
  # BuildResidentialScheduleFile
@@ -80,17 +80,17 @@ class MathTools
80
80
  end
81
81
 
82
82
  def self.interp2(x, x0, x1, f0, f1)
83
- '''
83
+ '
84
84
  Returns the linear interpolation between two results.
85
- '''
85
+ '
86
86
 
87
87
  return f0 + ((x - x0) / (x1 - x0)) * (f1 - f0)
88
88
  end
89
89
 
90
90
  def self.interp4(x, y, x1, x2, y1, y2, fx1y1, fx1y2, fx2y1, fx2y2)
91
- '''
91
+ '
92
92
  Returns the bilinear interpolation between four results.
93
- '''
93
+ '
94
94
 
95
95
  return (fx1y1 / ((x2 - x1) * (y2 - y1))) * (x2 - x) * (y2 - y) \
96
96
  + (fx2y1 / ((x2 - x1) * (y2 - y1))) * (x - x1) * (y2 - y) \
@@ -99,7 +99,7 @@ class MathTools
99
99
  end
100
100
 
101
101
  def self.biquadratic(x, y, c)
102
- '''
102
+ '
103
103
  Description:
104
104
  ------------
105
105
  Calculate the result of a biquadratic polynomial with independent variables
@@ -113,7 +113,7 @@ class MathTools
113
113
  Outputs:
114
114
  --------
115
115
  z float result of biquadratic polynomial
116
- '''
116
+ '
117
117
  if c.length != 6
118
118
  puts 'Error: There must be 6 coefficients in a biquadratic polynomial'
119
119
  end
@@ -122,7 +122,7 @@ class MathTools
122
122
  end
123
123
 
124
124
  def self.quadratic(x, c)
125
- '''
125
+ '
126
126
  Description:
127
127
  ------------
128
128
  Calculate the result of a quadratic polynomial with independent variable
@@ -138,7 +138,7 @@ class MathTools
138
138
  Outputs:
139
139
  --------
140
140
  y float result of biquadratic polynomial
141
- '''
141
+ '
142
142
  if c.size != 3
143
143
  puts 'Error: There must be 3 coefficients in a quadratic polynomial'
144
144
  end
@@ -148,7 +148,7 @@ class MathTools
148
148
  end
149
149
 
150
150
  def self.bicubic(x, y, c)
151
- '''
151
+ '
152
152
  Description:
153
153
  ------------
154
154
  Calculate the result of a bicubic polynomial with independent variables
@@ -166,7 +166,7 @@ class MathTools
166
166
  Outputs:
167
167
  --------
168
168
  z float result of bicubic polynomial
169
- '''
169
+ '
170
170
  if c.size != 10
171
171
  puts 'Error: There must be 10 coefficients in a bicubic polynomial'
172
172
  end
@@ -177,7 +177,7 @@ class MathTools
177
177
  end
178
178
 
179
179
  def self.Iterate(x0, f0, x1, f1, x2, f2, icount, cvg)
180
- '''
180
+ '
181
181
  Description:
182
182
  ------------
183
183
  Determine if a guess is within tolerance for convergence
@@ -225,7 +225,7 @@ class MathTools
225
225
  else:
226
226
  print "x did NOT converge after", i, "iterations"
227
227
  print "x, when f(x) is", f,"is", x
228
- '''
228
+ '
229
229
 
230
230
  tolRel = 1e-5
231
231
  dx = 0.1
@@ -987,16 +987,16 @@ class OutputMeters
987
987
  plant_loop.supplyComponents.each do |supply_component|
988
988
  next unless supply_component.to_BoilerHotWater.is_initialized
989
989
 
990
- if units_served.length != 1 # this is a central system
991
- if supply_component.to_BoilerHotWater.get.fuelType == 'Electricity'
992
- custom_meter_infos['Central:ElectricityHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Electric Energy']
993
- end
994
- custom_meter_infos['Central:ElectricityHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Ancillary Electric Energy']
995
- else
990
+ if units_served.length == 1
996
991
  if supply_component.to_BoilerHotWater.get.fuelType == 'Electricity'
997
992
  custom_meter_infos["#{unit.name}:ElectricityHeating"]['key_var_groups'] << [supply_component.name.to_s, 'Boiler Electric Energy']
998
993
  end
999
994
  custom_meter_infos["#{unit.name}:ElectricityHeating"]['key_var_groups'] << [supply_component.name.to_s, 'Boiler Ancillary Electric Energy']
995
+ else # this is a central system
996
+ if supply_component.to_BoilerHotWater.get.fuelType == 'Electricity'
997
+ custom_meter_infos['Central:ElectricityHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Electric Energy']
998
+ end
999
+ custom_meter_infos['Central:ElectricityHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Ancillary Electric Energy']
1000
1000
  end
1001
1001
  end
1002
1002
  end
@@ -1029,16 +1029,16 @@ class OutputMeters
1029
1029
  plant_loop.supplyComponents.each do |supply_component|
1030
1030
  next unless supply_component.to_BoilerHotWater.is_initialized
1031
1031
 
1032
- if units_served.length != 1 # this is a central system
1033
- if supply_component.to_BoilerHotWater.get.fuelType == 'Electricity'
1034
- custom_meter_infos['Central:ElectricityHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Electric Energy']
1035
- end
1036
- custom_meter_infos['Central:ElectricityHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Ancillary Electric Energy']
1037
- else
1032
+ if units_served.length == 1
1038
1033
  if supply_component.to_BoilerHotWater.get.fuelType == 'Electricity'
1039
1034
  custom_meter_infos["#{unit.name}:ElectricityHeating"]['key_var_groups'] << [supply_component.name.to_s, 'Boiler Electric Energy']
1040
1035
  end
1041
1036
  custom_meter_infos["#{unit.name}:ElectricityHeating"]['key_var_groups'] << [supply_component.name.to_s, 'Boiler Ancillary Electric Energy']
1037
+ else # this is a central system
1038
+ if supply_component.to_BoilerHotWater.get.fuelType == 'Electricity'
1039
+ custom_meter_infos['Central:ElectricityHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Electric Energy']
1040
+ end
1041
+ custom_meter_infos['Central:ElectricityHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Ancillary Electric Energy']
1042
1042
  end
1043
1043
  end
1044
1044
  end
@@ -1089,10 +1089,10 @@ class OutputMeters
1089
1089
  plant_loop.supplyComponents.each do |supply_component|
1090
1090
  next unless supply_component.to_ChillerElectricEIR.is_initialized
1091
1091
 
1092
- if units_served.length != 1 # this is a central system
1093
- custom_meter_infos['Central:ElectricityCooling']['key_var_groups'] << [supply_component.name.to_s, 'Chiller Electric Energy']
1094
- else
1092
+ if units_served.length == 1
1095
1093
  custom_meter_infos["#{unit.name}:ElectricityCooling"]['key_var_groups'] << [supply_component.name.to_s, 'Chiller Electric Energy']
1094
+ else # this is a central system
1095
+ custom_meter_infos['Central:ElectricityCooling']['key_var_groups'] << [supply_component.name.to_s, 'Chiller Electric Energy']
1096
1096
  end
1097
1097
  end
1098
1098
  end
@@ -1317,10 +1317,10 @@ class OutputMeters
1317
1317
  next unless supply_component.to_BoilerHotWater.is_initialized
1318
1318
  next if supply_component.to_BoilerHotWater.get.fuelType != 'NaturalGas'
1319
1319
 
1320
- if units_served.length != 1 # this is a central system
1321
- custom_meter_infos['Central:NaturalGasHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Gas Energy']
1322
- else
1320
+ if units_served.length == 1
1323
1321
  custom_meter_infos["#{unit.name}:NaturalGasHeating"]['key_var_groups'] << [supply_component.name.to_s, 'Boiler Gas Energy']
1322
+ else # this is a central system
1323
+ custom_meter_infos['Central:NaturalGasHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Gas Energy']
1324
1324
  end
1325
1325
  end
1326
1326
  end
@@ -1350,10 +1350,10 @@ class OutputMeters
1350
1350
  next unless supply_component.to_BoilerHotWater.is_initialized
1351
1351
  next if supply_component.to_BoilerHotWater.get.fuelType != 'NaturalGas'
1352
1352
 
1353
- if units_served.length != 1 # this is a central system
1354
- custom_meter_infos['Central:NaturalGasHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Gas Energy']
1355
- else
1353
+ if units_served.length == 1
1356
1354
  custom_meter_infos["#{unit.name}:NaturalGasHeating"]['key_var_groups'] << [supply_component.name.to_s, 'Boiler Gas Energy']
1355
+ else # this is a central system
1356
+ custom_meter_infos['Central:NaturalGasHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Gas Energy']
1357
1357
  end
1358
1358
  end
1359
1359
  end
@@ -1446,10 +1446,10 @@ class OutputMeters
1446
1446
  next unless supply_component.to_BoilerHotWater.is_initialized
1447
1447
  next if supply_component.to_BoilerHotWater.get.fuelType != 'FuelOil#1'
1448
1448
 
1449
- if units_served.length != 1 # this is a central system
1450
- custom_meter_infos['Central:FuelOilHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler FuelOil#1 Energy']
1451
- else
1449
+ if units_served.length == 1
1452
1450
  custom_meter_infos["#{unit.name}:FuelOilHeating"]['key_var_groups'] << [supply_component.name.to_s, 'Boiler FuelOil#1 Energy']
1451
+ else # this is a central system
1452
+ custom_meter_infos['Central:FuelOilHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler FuelOil#1 Energy']
1453
1453
  end
1454
1454
  end
1455
1455
  end
@@ -1479,10 +1479,10 @@ class OutputMeters
1479
1479
  next unless supply_component.to_BoilerHotWater.is_initialized
1480
1480
  next if supply_component.to_BoilerHotWater.get.fuelType != 'FuelOil#1'
1481
1481
 
1482
- if units_served.length != 1 # this is a central system
1483
- custom_meter_infos['Central:FuelOilHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler FuelOil#1 Energy']
1484
- else
1482
+ if units_served.length == 1
1485
1483
  custom_meter_infos["#{unit.name}:FuelOilHeating"]['key_var_groups'] << [supply_component.name.to_s, 'Boiler FuelOil#1 Energy']
1484
+ else # this is a central system
1485
+ custom_meter_infos['Central:FuelOilHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler FuelOil#1 Energy']
1486
1486
  end
1487
1487
  end
1488
1488
  end
@@ -1549,10 +1549,10 @@ class OutputMeters
1549
1549
  next unless supply_component.to_BoilerHotWater.is_initialized
1550
1550
  next if supply_component.to_BoilerHotWater.get.fuelType != 'PropaneGas'
1551
1551
 
1552
- if units_served.length != 1 # this is a central system
1553
- custom_meter_infos['Central:PropaneHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Propane Energy']
1554
- else
1552
+ if units_served.length == 1
1555
1553
  custom_meter_infos["#{unit.name}:PropaneHeating"]['key_var_groups'] << [supply_component.name.to_s, 'Boiler Propane Energy']
1554
+ else # this is a central system
1555
+ custom_meter_infos['Central:PropaneHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Propane Energy']
1556
1556
  end
1557
1557
  end
1558
1558
  end
@@ -1582,10 +1582,10 @@ class OutputMeters
1582
1582
  next unless supply_component.to_BoilerHotWater.is_initialized
1583
1583
  next if supply_component.to_BoilerHotWater.get.fuelType != 'PropaneGas'
1584
1584
 
1585
- if units_served.length != 1 # this is a central system
1586
- custom_meter_infos['Central:PropaneHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Propane Energy']
1587
- else
1585
+ if units_served.length == 1
1588
1586
  custom_meter_infos["#{unit.name}:PropaneHeating"]['key_var_groups'] << [supply_component.name.to_s, 'Boiler Propane Energy']
1587
+ else # this is a central system
1588
+ custom_meter_infos['Central:PropaneHeating']['key_var_groups'] << [supply_component.name.to_s, 'Boiler Propane Energy']
1589
1589
  end
1590
1590
  end
1591
1591
  end
@@ -40,6 +40,6 @@
40
40
 
41
41
  module URBANopt
42
42
  module CLI
43
- VERSION = '0.9.1'.freeze
43
+ VERSION = '0.9.2'.freeze
44
44
  end
45
45
  end
data/lib/uo_cli.rb CHANGED
@@ -453,26 +453,26 @@ module URBANopt
453
453
  # One solution would be changing scenario_file to feature.
454
454
  # Would that be confusing when creating a ScenarioFile from the FeatureFile?
455
455
  if @opthash.subopts[:feature]
456
- @feature_path, @feature_name = File.split(File.expand_path(@opthash.subopts[:feature]))
456
+ @feature_path, @feature_name = Pathname(File.expand_path(@opthash.subopts[:feature])).split
457
457
  end
458
458
  if @opthash.subopts[:scenario]
459
- @root_dir, @scenario_file_name = File.split(File.expand_path(@opthash.subopts[:scenario]))
459
+ @root_dir, @scenario_file_name = Pathname(File.expand_path(@opthash.subopts[:scenario])).split
460
460
  @scenario_name = File.basename(@scenario_file_name, File.extname(@scenario_file_name))
461
461
  end
462
462
 
463
463
  # Simulate energy usage as defined by ScenarioCSV
464
464
  def self.run_func
465
- run_dir = File.join(@root_dir, 'run', @scenario_name.downcase)
466
- csv_file = File.join(@root_dir, @scenario_file_name)
467
- featurefile = File.join(@root_dir, @feature_name)
468
- mapper_files_dir = File.join(@root_dir, 'mappers')
469
- reopt_files_dir = File.join(@root_dir, 'reopt/')
465
+ run_dir = @root_dir / 'run' / @scenario_name.downcase
466
+ csv_file = @root_dir / @scenario_file_name
467
+ featurefile = @root_dir / @feature_name
468
+ mapper_files_dir = @root_dir / 'mappers'
469
+ reopt_files_dir = @root_dir / 'reopt/'
470
470
  num_header_rows = 1
471
471
 
472
472
  if @feature_id
473
- feature_run_dir = File.join(run_dir, @feature_id)
473
+ feature_run_dir = run_dir / @feature_id
474
474
  # If run folder for feature exists, remove it
475
- FileUtils.rm_rf(feature_run_dir) if File.exist?(feature_run_dir)
475
+ FileUtils.rm_rf(feature_run_dir) if feature_run_dir.exist?
476
476
  end
477
477
 
478
478
  feature_file = URBANopt::GeoJSON::GeoFile.from_file(featurefile)
@@ -578,6 +578,26 @@ module URBANopt
578
578
  end
579
579
  end
580
580
 
581
+ # Change num_parallel in runner.conf to set number of cores to use when running simulations
582
+ # This function is called during project_dir creation/updating so users aren't surprised if they look at the config file
583
+ def self.use_num_parallel(project_dir)
584
+ if ENV['UO_NUM_PARALLEL'] || @opthash.subopts[:num_parallel]
585
+ runner_file_path = Pathname(project_dir) / 'runner.conf'
586
+ runner_conf_hash = JSON.parse(File.read(runner_file_path))
587
+ if @opthash.subopts[:num_parallel]
588
+ runner_conf_hash['num_parallel'] = @opthash.subopts[:num_parallel]
589
+ File.open(runner_file_path, 'w+') do |f|
590
+ f << runner_conf_hash.to_json
591
+ end
592
+ elsif ENV['UO_NUM_PARALLEL']
593
+ runner_conf_hash['num_parallel'] = ENV['UO_NUM_PARALLEL'].to_i
594
+ File.open(runner_file_path, 'w+') do |f|
595
+ f << runner_conf_hash.to_json
596
+ end
597
+ end
598
+ end
599
+ end
600
+
581
601
  # Create project folder
582
602
  # params\
583
603
  # +dir_name+:: _string_ Name of new project folder
@@ -617,15 +637,7 @@ module URBANopt
617
637
 
618
638
  # copy config file
619
639
  FileUtils.cp(File.join(path_item, 'runner.conf'), dir_name)
620
- # If the env var is set, change the num_parallel value to be what the env var is set to
621
- if ENV['UO_NUM_PARALLEL']
622
- runner_file_path = File.join(dir_name, 'runner.conf')
623
- runner_conf_hash = JSON.parse(File.read(runner_file_path))
624
- runner_conf_hash['num_parallel'] = ENV['UO_NUM_PARALLEL'].to_i
625
- File.open(runner_file_path, 'w+') do |f|
626
- f << runner_conf_hash.to_json
627
- end
628
- end
640
+ use_num_parallel(dir_name)
629
641
 
630
642
  # copy gemfile
631
643
  FileUtils.cp(File.join(path_item, 'Gemfile'), dir_name)
@@ -681,6 +693,9 @@ module URBANopt
681
693
  FileUtils.cp(File.join(path_item, 'mappers/ThermalStorage.rb'), File.join(dir_name, 'mappers'))
682
694
  FileUtils.cp(File.join(path_item, 'mappers/EvCharging.rb'), File.join(dir_name, 'mappers'))
683
695
  FileUtils.cp(File.join(path_item, 'mappers/FlexibleHotWater.rb'), File.join(dir_name, 'mappers'))
696
+ FileUtils.cp(File.join(path_item, 'mappers/ChilledWaterStorage.rb'), File.join(dir_name, 'mappers'))
697
+ FileUtils.cp(File.join(path_item, 'mappers/PeakHoursThermostatAdjust.rb'), File.join(dir_name, 'mappers'))
698
+ FileUtils.cp(File.join(path_item, 'mappers/PeakHoursMelsShedding.rb'), File.join(dir_name, 'mappers'))
684
699
 
685
700
  # copy osw file
686
701
  FileUtils.cp(File.join(path_item, 'mappers/base_workflow.osw'), File.join(dir_name, 'mappers'))
@@ -811,19 +826,10 @@ module URBANopt
811
826
 
812
827
  # copy config file
813
828
  FileUtils.cp_r(File.join(path_item, 'runner.conf'), new_path, remove_destination: true)
814
- # If the env var is set, change the num_parallel value to be what the env var is set to
815
- # TODO: make this into a function...it's used in 2 places
816
- if ENV['UO_NUM_PARALLEL']
817
- runner_file_path = File.join(new_path, 'runner.conf')
818
- runner_conf_hash = JSON.parse(File.read(runner_file_path))
819
- runner_conf_hash['num_parallel'] = ENV['UO_NUM_PARALLEL'].to_i
820
- File.open(runner_file_path, 'w+') do |f|
821
- f << runner_conf_hash.to_json
822
- end
823
- end
829
+ use_num_parallel(new_path)
824
830
 
825
831
  # Replace standard mappers
826
- # Note: this also copies createBar and Floorspace without checking project type (for now)
832
+ # FIXME: this also copies createBar and Floorspace without checking project type (for now)
827
833
  mappers = File.join(path_item, 'mappers')
828
834
  Pathname.new(mappers).children.each { |mapper| FileUtils.cp_r(mapper, File.join(new_path, 'mappers'), remove_destination: true) }
829
835
 
@@ -920,7 +926,7 @@ module URBANopt
920
926
  # Return UO python packages list from python_deps/dependencies.json
921
927
  def self.get_python_deps
922
928
  deps = []
923
- the_path = ""
929
+ the_path = ''
924
930
  $LOAD_PATH.each do |path_item|
925
931
  if path_item.to_s.end_with?('example_files')
926
932
  # install python in cli gem's example_files/python_deps folder
@@ -980,18 +986,18 @@ module URBANopt
980
986
  puts "DEPENDENCIES RETRIEVED FROM FILE: #{deps}"
981
987
  errors = []
982
988
  deps.each do |dep|
983
- #TODO: Update when there is a stable release for DISCO
984
- if dep[:name].to_s.include? "disco"
989
+ # TODO: Update when there is a stable release for DISCO
990
+ if dep[:name].to_s.include? 'disco'
985
991
  stdout, stderr, status = Open3.capture3("#{pvars[:pip_path]} show NREL-disco")
986
- else
992
+ else
987
993
  stdout, stderr, status = Open3.capture3("#{pvars[:pip_path]} show #{dep[:name]}")
988
994
  end
989
995
  if stderr.empty?
990
996
  # check versions
991
- m = stdout.match /^Version: (\S{3,}$)/
997
+ m = stdout.match(/^Version: (\S{3,}$)/)
992
998
  err = true
993
- if m and m.size > 1
994
- if !dep[:version].nil? and dep[:version].to_s == m[1].to_s
999
+ if m && m.size > 1
1000
+ if !dep[:version].nil? && dep[:version].to_s == m[1].to_s
995
1001
  puts "...#{dep[:name]} found with specified version #{dep[:version]}"
996
1002
  err = false
997
1003
  elsif dep[:version].nil?
@@ -1107,14 +1113,14 @@ module URBANopt
1107
1113
  deps = get_python_deps
1108
1114
  deps.each do |dep|
1109
1115
  puts "Installing #{dep[:name]}..."
1110
- the_command = ""
1116
+ the_command = ''
1111
1117
  if dep[:version].nil?
1112
1118
  the_command = "#{pvars[:pip_path]} install #{dep[:name]}"
1113
1119
  else
1114
1120
  the_command = "#{pvars[:pip_path]} install #{dep[:name]}~=#{dep[:version]}"
1115
1121
  end
1116
1122
  # system(the_command)
1117
- #puts "INSTALL COMMAND: #{the_command}"
1123
+ # puts "INSTALL COMMAND: #{the_command}"
1118
1124
  stdout, stderr, status = Open3.capture3(the_command)
1119
1125
  if stderr && !stderr == ''
1120
1126
  puts "Error installing: #{stderr}"
@@ -1197,7 +1203,7 @@ module URBANopt
1197
1203
  @opthash.subopts[:scenario_file].nil? &&
1198
1204
  @opthash.subopts[:reopt_scenario_file].nil? &&
1199
1205
  @opthash.subopts[:project_folder].nil?
1200
- abort("\nNo options provided to the `create` command. Did you forget the `-p` flag? See `uo create --help` for all options\n")
1206
+ abort("\nNo options provided for the `create` command. Did you forget a flag? Perhaps `-p`? See `uo create --help` for all options\n")
1201
1207
  end
1202
1208
 
1203
1209
  # Update existing URBANopt Project files
@@ -1217,26 +1223,10 @@ module URBANopt
1217
1223
 
1218
1224
  # Run simulations
1219
1225
  if @opthash.command == 'run' && @opthash.subopts[:scenario] && @opthash.subopts[:feature]
1220
- # Change num_parallel in runner.conf - Use case is for CI to use more cores
1221
- # If set by env variable, use that, otherwise use what the user specified in the cli
1222
- if ENV['UO_NUM_PARALLEL'] || @opthash.subopts[:num_parallel]
1223
- runner_file_path = File.join(@root_dir, 'runner.conf')
1224
- runner_conf_hash = JSON.parse(File.read(runner_file_path))
1225
- if @opthash.subopts[:num_parallel]
1226
- runner_conf_hash['num_parallel'] = @opthash.subopts[:num_parallel]
1227
- File.open(runner_file_path, 'w+') do |f|
1228
- f << runner_conf_hash.to_json
1229
- end
1230
- elsif ENV['UO_NUM_PARALLEL']
1231
- runner_conf_hash['num_parallel'] = ENV['UO_NUM_PARALLEL'].to_i
1232
- File.open(runner_file_path, 'w+') do |f|
1233
- f << runner_conf_hash.to_json
1234
- end
1235
- end
1236
- end
1226
+ use_num_parallel(@root_dir)
1237
1227
 
1238
1228
  if @opthash.subopts[:scenario].to_s.include? '-'
1239
- @feature_id = (@feature_name.split(/\W+/)[1]).to_s
1229
+ @feature_id = (@feature_name.to_s.split(/\W+/)[1])
1240
1230
  end
1241
1231
 
1242
1232
  puts "\nSimulating features of '#{@feature_name}' as directed by '#{@scenario_file_name}'...\n\n"
@@ -1414,12 +1404,12 @@ module URBANopt
1414
1404
  commands.each do |command|
1415
1405
  # TODO: This will be updated so stderr only reports error/warnings at DISCO level
1416
1406
  stdout, stderr, status = Open3.capture3(command)
1417
- if !stderr.empty?
1407
+ if !stderr.empty?
1418
1408
  puts "ERROR running DISCO: #{stderr}"
1419
1409
  end
1420
1410
  end
1421
- puts "Refer to detailed log file #{File.join(run_folder,'disco','run_upgrade_cost_analysis.log')} for more information on the run."
1422
- puts "Refer to the output summary file #{File.join(run_folder,'disco','output_summary.json')} for a summary of the results."
1411
+ puts "Refer to detailed log file #{File.join(run_folder, 'disco', 'run_upgrade_cost_analysis.log')} for more information on the run."
1412
+ puts "Refer to the output summary file #{File.join(run_folder, 'disco', 'output_summary.json')} for a summary of the results."
1423
1413
  end
1424
1414
  end
1425
1415
 
@@ -1459,7 +1449,7 @@ module URBANopt
1459
1449
 
1460
1450
  # Post-process the scenario
1461
1451
  if @opthash.command == 'process'
1462
- if @opthash.subopts[:default] == false && @opthash.subopts[:opendss] == false && @opthash.subopts[:reopt_scenario] == false && @opthash.subopts[:reopt_feature] == false && @opthash.subopts[:disco] == false
1452
+ if @opthash.subopts[:default] == false && @opthash.subopts[:opendss] == false && @opthash.subopts[:reopt_scenario] == false && @opthash.subopts[:reopt_feature] == false && @opthash.subopts[:disco] == false
1463
1453
  abort("\nERROR: No valid process type entered. Must enter a valid process type\n")
1464
1454
  end
1465
1455
 
@@ -1720,12 +1710,17 @@ module URBANopt
1720
1710
  abort("\nERROR: Units type not recognized. Please use a valid option in the CLI")
1721
1711
  end
1722
1712
  building_type = feature[:properties][:building_type] # From FeatureFile
1723
- if feature_eui_value > validation_params['EUI'][@opthash.subopts[:units]][building_type]['max']
1724
- puts "\nFeature #{File.basename(feature_path)} EUI of #{feature_eui_value.round(2)} #{unit_value} is greater than the validation maximum."
1725
- elsif feature_eui_value < validation_params['EUI'][@opthash.subopts[:units]][building_type]['min']
1726
- puts "\nFeature #{File.basename(feature_path)} (#{building_type}) EUI of #{feature_eui_value.round(2)} #{unit_value} is less than the validation minimum."
1713
+ validation_upper_limit = validation_params['EUI'][@opthash.subopts[:units]][building_type]['max']
1714
+ validation_lower_limit = validation_params['EUI'][@opthash.subopts[:units]][building_type]['min']
1715
+ if feature_eui_value > validation_upper_limit
1716
+ puts "\nFeature #{File.basename(feature_path)} (#{building_type}) EUI of #{feature_eui_value.round(2)} #{unit_value} " \
1717
+ "is greater than the validation maximum of #{validation_upper_limit}."
1718
+ elsif feature_eui_value < validation_lower_limit
1719
+ puts "\nFeature #{File.basename(feature_path)} (#{building_type}) EUI of #{feature_eui_value.round(2)} #{unit_value} " \
1720
+ "is less than the validation minimum of #{validation_lower_limit}."
1727
1721
  else
1728
- puts "\nFeature #{File.basename(feature_path)} (#{building_type}) EUI of #{feature_eui_value.round(2)} #{unit_value} is within bounds set by #{validation_file_name}."
1722
+ puts "\nFeature #{File.basename(feature_path)} (#{building_type}) EUI of #{feature_eui_value.round(2)} #{unit_value} " \
1723
+ "is within bounds set by #{validation_file_name} (#{validation_lower_limit} - #{validation_upper_limit})."
1729
1724
  end
1730
1725
  end
1731
1726
  end
data/uo_cli.gemspec CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.require_paths = ['lib', 'example_files']
33
33
  spec.required_ruby_version = '~> 2.7.0'
34
34
 
35
- # use specific versions of urbanopt and openstudio dependencies while under heavy development
35
+ # use specific versions of urbanopt and openstudio dependencies while under heavy development
36
36
  spec.add_runtime_dependency 'optimist', '~> 3'
37
37
  spec.add_runtime_dependency 'urbanopt-geojson', '~> 0.9.0'
38
38
  spec.add_runtime_dependency 'urbanopt-reopt', '~> 0.9.0'
@@ -47,4 +47,6 @@ Gem::Specification.new do |spec|
47
47
  spec.add_development_dependency 'rubocop', '~> 1.15.0'
48
48
  spec.add_development_dependency 'rubocop-checkstyle_formatter', '~> 0.4.0'
49
49
  spec.add_development_dependency 'rubocop-performance', '~> 1.11.3'
50
+ spec.add_development_dependency 'simplecov', '~> 0.18.2'
51
+ spec.add_development_dependency 'simplecov-lcov', '~> 0.8.0'
50
52
  end
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.9.1
4
+ version: 0.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Moore
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-06 00:00:00.000000000 Z
11
+ date: 2023-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: optimist
@@ -178,6 +178,34 @@ dependencies:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
180
  version: 1.11.3
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 0.18.2
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 0.18.2
195
+ - !ruby/object:Gem::Dependency
196
+ name: simplecov-lcov
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: 0.8.0
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: 0.8.0
181
209
  description: Interfacing with URBANopt
182
210
  email:
183
211
  - nathan.moore@nrel.gov
@@ -189,6 +217,7 @@ files:
189
217
  - ".github/ISSUE_TEMPLATE/bug_report.md"
190
218
  - ".github/ISSUE_TEMPLATE/feature_request.md"
191
219
  - ".github/pull_request_template.md"
220
+ - ".github/workflows/nightly_build.yml"
192
221
  - ".gitignore"
193
222
  - ".rspec"
194
223
  - ".rubocop.yml"
@@ -1087,7 +1116,6 @@ files:
1087
1116
  - example_files/xml_building/17/unit 4.xml
1088
1117
  - lib/uo_cli.rb
1089
1118
  - lib/uo_cli/version.rb
1090
- - requirements.txt
1091
1119
  - scripts/setup-env-gitbash.sh
1092
1120
  - scripts/setup-env-unix.sh
1093
1121
  - scripts/setup-env.bat
data/requirements.txt DELETED
@@ -1,2 +0,0 @@
1
- geojson-modelica-translator~=0.2.2
2
- urbanopt-ditto-reader~=0.3.8