diff --git a/codes/T24_2025_new.csv b/codes/T24_2025_new.csv index 3b81bc32..dd258909 100644 --- a/codes/T24_2025_new.csv +++ b/codes/T24_2025_new.csv @@ -596,3 +596,155 @@ Climate Zone,Fixed Drybulb,Differential Dry-bulb,,, 14,75,0,,, 15,75,0,,, 16,75,0,,, +,,,,, +table: CW Pump Min Flow Rate ECC,,,,, +Climate Zone,CW Pump Min Flow Rate,Note,,, +1,75.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +2,105.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +3,97.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +4,106.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +5,91.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +6,96.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +7,99.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +8,108.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +9,109.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +10,119.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +11,109.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +12,109.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +13,113,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +14,112.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +15,117.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +16,98.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +,,,,, +table: CW Pump Min Flow Rate ESe,,,,, +Climate Zone,CW Pump Min Flow Rate,Note,,, +1,11.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +2,16.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +3,15.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +4,16.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +5,14.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +6,15.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +7,15.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +8,17.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +9,17.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +10,18.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +11,16.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +12,16.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +13,16.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +14,16.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +15,17.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +16,14.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +,,,,, +table: CW Pump Min Flow Rate EUn,,,,, +Climate Zone,CW Pump Min Flow Rate,Note,,, +1,177.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +2,213.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +3,206.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +4,215.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +5,191.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +6,201.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +7,208.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +8,217.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +9,214.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +10,235.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +11,230.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +12,226.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +13,235.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +14,236.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +15,245.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +16,207.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +,,,,, +table: CW Pump Min Flow Rate Hsp,,,,, +Climate Zone,CW Pump Min Flow Rate,Note,,, +1,99.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +2,134,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +3,126,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +4,135.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +5,120.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +6,126.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +7,128.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +8,137.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +9,141.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +10,149.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +11,129.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +12,130.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +13,133.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +14,133.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +15,138,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +16,121,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +,,,,, +table: CW Pump Min Flow Rate Nrs,,,,, +Climate Zone,CW Pump Min Flow Rate,Note,,, +1,10.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +2,13.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +3,13.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +4,14,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +5,12.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +6,13.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +7,13.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +8,14.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +9,13.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +10,15.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +11,15.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +12,15.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +13,16,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +14,16,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +15,16.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +16,13.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +,,,,, +table: CW Pump Min Flow Rate OfL,,,,, +Climate Zone,CW Pump Min Flow Rate,Note,,, +1,62.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +2,78.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +3,74.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +4,78.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +5,70.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +6,73,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +7,74.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +8,79.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +9,77.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +10,86.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +11,86.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +12,84.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +13,87.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +14,88.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +15,91.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +16,81.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +,,,,, +table: CW Pump Min Flow Rate OfS,,,,, +Climate Zone,CW Pump Min Flow Rate,Note,,, +1,3.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +2,4.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +3,4.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +4,4.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +5,4.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +6,4.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +7,4.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +8,5.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +9,4.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +10,5.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +11,5.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +12,5.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +13,5.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +14,5.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +15,5.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +16,5.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +,,,,, +table: CW Pump Min Flow Rate Rt3,,,,, +Climate Zone,CW Pump Min Flow Rate,Note,,, +1,45.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +2,80.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +3,74.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +4,82.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +5,70.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +6,76,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +7,77.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +8,85.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +9,90.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +10,92.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +11,65.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +12,66.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +13,69.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +14,68.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +15,73,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +16,58,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, diff --git a/codes/T24_2025_new_Htl.csv b/codes/T24_2025_new_Htl.csv index d1d3c1d9..55732603 100644 --- a/codes/T24_2025_new_Htl.csv +++ b/codes/T24_2025_new_Htl.csv @@ -452,3 +452,22 @@ Climate Zone,Fixed Drybulb,Differential Dry-bulb,,, 14,75,0,,, 15,75,0,,, 16,75,0,,, +,,,,, +table: CW Pump Min Flow Rate Htl,,,,, +Climate Zone,CW Pump Min Flow Rate,Note,,, +1,10.5345625,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +2,13.754482,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +3,12.967437,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +4,13.9446265,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +5,12.0306445,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +6,12.7522185,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +7,13.40066,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +8,14.1828295,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +9,14.0769615,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +10,15.786869,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +11,15.980496,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +12,15.75483,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +13,16.4374,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +14,16.50705,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +15,17.007137,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, +16,14.077658,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),,, diff --git a/codes/T24_weight_averaged_ex.csv b/codes/T24_weight_averaged_ex.csv index 58a644b5..142f27b1 100644 --- a/codes/T24_weight_averaged_ex.csv +++ b/codes/T24_weight_averaged_ex.csv @@ -608,3 +608,155 @@ Climate Zone,Fixed Drybulb,Differential Dry-bulb,, 14,75,0,, 15,75,0,, 16,75,0,, +,,,, +table: CW Pump Min Flow Rate ECC,,,, +Climate Zone,CW Pump Min Flow Rate,Notes,, +1,97.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +2,125.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +3,117.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +4,126.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +5,111.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +6,116.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +7,119.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +8,127.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +9,129.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +10,139,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +11,140.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +12,137.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +13,141.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +14,141.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +15,146.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +16,124,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +,,,, +table: CW Pump Min Flow Rate ESe,,,, +Climate Zone,CW Pump Min Flow Rate,,, +1,16.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +2,20.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +3,19.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +4,21.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +5,18.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +6,19.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +7,19.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +8,21.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +9,21.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +10,22.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +11,23,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +12,22.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +13,23,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +14,23,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +15,23.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +16,20.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +,,,, +table: CW Pump Min Flow Rate EUn,,,, +Climate Zone,CW Pump Min Flow Rate,,, +1,249.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +2,296,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +3,286.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +4,298.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +5,271.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +6,280.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +7,285.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +8,300.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +9,305.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +10,310.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +11,319.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +12,311.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +13,320.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +14,320.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +15,328.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +16,291,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +,,,, +table: CW Pump Min Flow Rate Hsp,,,, +Climate Zone,CW Pump Min Flow Rate,,, +1,117,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +2,143.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +3,136.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +4,145.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +5,132,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +6,137.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +7,140.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +8,147.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +9,151,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +10,160.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +11,158.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +12,154.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +13,160.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +14,159.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +15,164.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +16,144.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +,,,, +table: CW Pump Min Flow Rate Nrs,,,, +Climate Zone,CW Pump Min Flow Rate,,, +1,14.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +2,19,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +3,17.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +4,19.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +5,16.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +6,17.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +7,17.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +8,19.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +9,19.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +10,20.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +11,21.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +12,20.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +13,21.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +14,21.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +15,21.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +16,18.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +,,,, +table: CW Pump Min Flow Rate OfL,,,, +Climate Zone,CW Pump Min Flow Rate,,, +1,96.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +2,120.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +3,113.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +4,121,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +5,109.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +6,111.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +7,111.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +8,120.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +9,123,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +10,123.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +11,130.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +12,125.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +13,128.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +14,130.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +15,132.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +16,120.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +,,,, +table: CW Pump Min Flow Rate OfS,,,, +Climate Zone,CW Pump Min Flow Rate,,, +1,7.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +2,9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +3,8.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +4,9.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +5,8.3,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +6,8.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +7,8.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +8,9.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +9,9.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +10,8.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +11,9.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +12,9.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +13,9.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +14,9.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +15,9.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +16,9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +,,,, +table: CW Pump Min Flow Rate Rt3,,,, +Climate Zone,CW Pump Min Flow Rate,,, +1,64,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +2,85.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +3,80.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +4,87.2,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +5,76.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +6,81.8,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +7,85.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +8,89.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +9,93.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +10,100.6,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +11,95.1,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +12,91.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +13,96.7,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +14,94.4,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +15,99.5,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +16,81.9,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, diff --git a/codes/T24_weight_averaged_ex_Htl.csv b/codes/T24_weight_averaged_ex_Htl.csv index 5f8e893f..66bff41d 100644 --- a/codes/T24_weight_averaged_ex_Htl.csv +++ b/codes/T24_weight_averaged_ex_Htl.csv @@ -478,3 +478,22 @@ Climate Zone,Fixed Drybulb,Differential Dry-bulb,, 14,75,0,, 15,75,0,, 16,75,0,, +,,,, +table: CW Pump Min Flow Rate Htl,,,, +Climate Zone,CW Pump Min Flow Rate,Note,, +1,11.9442785,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +2,15.9602975,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +3,15.026291,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +4,16.1831775,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +5,13.853385,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +6,14.6146595,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +7,14.903707,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +8,16.351034,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +9,16.3851625,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +10,17.854081,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +11,18.487896,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +12,17.8784585,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +13,18.7212235,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +14,18.519935,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +15,19.171859,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, +16,16.156014,This table is designed specifically for the SWHC008 modeling setup. 70% of autosized design flow from standard techID (.eio),, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/.modelkit-config b/commercial measures/SWHC008-04 VSD Central Plant/.modelkit-config new file mode 100644 index 00000000..b11027e5 --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/.modelkit-config @@ -0,0 +1,24 @@ + +# Paths are expanded relative to this modelkit-config file. + +prototypes-dir = '../../prototypes' +templates-dir = '../../templates/energyplus/templates' +weather-dir = '../../weather' +codes-dir = '../../codes' + +max-workers = 12 # Maximum number of simulations to run in parallel + + +[template-compose] +annotate = true +indent = " " +esc-line = "! " +dirs = '~\Documents\Modelkit Caboodle\templates\energyplus\templates' # Must be an absolute path + +[energyplus-run] +engine = 'C:\EnergyPlusV22-2-0' # Must be an absolute path +#engine = '/Applications/EnergyPlus-22-2-0' # Must be an absolute path +#engine = '/Applications/EnergyPlus-9-2-0' # Must be an absolute path +readvars = true +keep = false +output-files = "eplusout.err; eplusout.sql; eplustbl.htm; eplusvar.csv" diff --git a/commercial measures/SWHC008-04 VSD Central Plant/CW_pump_flowrate.xlsx b/commercial measures/SWHC008-04 VSD Central Plant/CW_pump_flowrate.xlsx new file mode 100644 index 00000000..7ae912ef Binary files /dev/null and b/commercial measures/SWHC008-04 VSD Central Plant/CW_pump_flowrate.xlsx differ diff --git a/commercial measures/SWHC008-04 VSD Central Plant/DEER_EnergyPlus_Modelkit_Measure_list_working.xlsx b/commercial measures/SWHC008-04 VSD Central Plant/DEER_EnergyPlus_Modelkit_Measure_list_working.xlsx new file mode 100644 index 00000000..ce7127ba Binary files /dev/null and b/commercial measures/SWHC008-04 VSD Central Plant/DEER_EnergyPlus_Modelkit_Measure_list_working.xlsx differ diff --git a/commercial measures/SWHC008-04 VSD Central Plant/README.md b/commercial measures/SWHC008-04 VSD Central Plant/README.md new file mode 100644 index 00000000..df738f0b --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/README.md @@ -0,0 +1,18 @@ +# SWHC008-04 VSD Central Plant + +## Unconventional aspects of measure setup + +Note that this measure uses condenser water pump minimum flow rate lookup as a +function of cohort (building type/vintage) and climate zone. Based on modelkit +and rakefile capabilities during development, measure developers chose to store +the lookup values in the codes files, although these are based on measure +definition, not code requirements. + +See related files: + +- commercial measures/SWHC008-04 VSD Central Plant/CW_pump_flowrate.xlsx +- commercial measures/SWHC008-04 VSD Central Plant/pump_min_flow.csv +- codes/T24_2025_new.csv +- codes/T24_2025_new_Htl.csv +- codes/T24_weight_averaged_ex.csv +- codes/T24_weight_averaged_ex_Htl.csv diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/ECC&0&cPVVE&Ex&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/ECC&0&cPVVE&Ex&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/ECC&0&cPVVE&Ex&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/ESe&0&cPVVE&Ex&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/ESe&0&cPVVE&Ex&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/ESe&0&cPVVE&Ex&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/EUn&0&cPVVE&Ex&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/EUn&0&cPVVE&Ex&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/EUn&0&cPVVE&Ex&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/Hsp&0&cPVVE&Ex&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/Hsp&0&cPVVE&Ex&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/Hsp&0&cPVVE&Ex&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/Nrs&0&cPVVE&Ex&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/Nrs&0&cPVVE&Ex&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/Nrs&0&cPVVE&Ex&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/OfL&0&cPVVE&Ex&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/OfL&0&cPVVE&Ex&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/OfL&0&cPVVE&Ex&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/OfS&0&cPVVE&Ex&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/OfS&0&cPVVE&Ex&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/OfS&0&cPVVE&Ex&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/Rt3&0&cPVVE&Ex&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/Rt3&0&cPVVE&Ex&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cases/Rt3&0&cPVVE&Ex&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/climates.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/climates.csv new file mode 100644 index 00000000..2b7ad0aa --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/climates.csv @@ -0,0 +1,17 @@ +skip,climate,weather_file,climate_zone,codes_file +,CZ01,CA_EUREKA_725940S_CZ2022.epw,1,T24_weight_averaged_ex.csv +,CZ02,CA_NAPA-CO_724955S_CZ2022.epw,2,T24_weight_averaged_ex.csv +,CZ03,CA_OAKLAND-METRO-AP_724930S_CZ2022.epw,3,T24_weight_averaged_ex.csv +,CZ04,CA_SAN-JOSE-IAP_724945S_CZ2022.epw,4,T24_weight_averaged_ex.csv +,CZ05,CA_SANTA-MARIA-PUBLIC-AP_723940S_CZ2022.epw,5,T24_weight_averaged_ex.csv +,CZ06,CA_LOS-ANGELES-IAP_722950S_CZ2022.epw,6,T24_weight_averaged_ex.csv +,CZ07,CA_SAN-DIEGO-LINDBERGH-FLD_722900S_CZ2022.epw,7,T24_weight_averaged_ex.csv +,CZ08,CA_LONG-BEACH-DAUGHERTY-FLD_722970S_CZ2022.epw,8,T24_weight_averaged_ex.csv +,CZ09,CA_LOS-ANGELES-DOWNTOWN-USC_722874S_CZ2022.epw,9,T24_weight_averaged_ex.csv +,CZ10,CA_RIVERSIDE-MUNI_722869S_CZ2022.epw,10,T24_weight_averaged_ex.csv +,CZ11,CA_RED-BLUFF-MUNI-AP_725910S_CZ2022.epw,11,T24_weight_averaged_ex.csv +,CZ12,CA_STOCKTON-METRO-AP_724920S_CZ2022.epw,12,T24_weight_averaged_ex.csv +,CZ13,CA_FRESNO-YOSEMITE-IAP_723890S_CZ2022.epw,13,T24_weight_averaged_ex.csv +,CZ14,CA_DAGGETT-BARSTOW-AP_723815S_CZ2022.epw,14,T24_weight_averaged_ex.csv +,CZ15,CA_EL-CENTRO-NAF_722810S_CZ2022.epw,15,T24_weight_averaged_ex.csv +,CZ16,CA_BISHOP-AP_724800S_CZ2022.epw,16,T24_weight_averaged_ex.csv diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cohorts.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cohorts.csv new file mode 100644 index 00000000..a22d2e2b --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/cohorts.csv @@ -0,0 +1,27 @@ +skip,cohort,root,wall_type,:wall_base_cavity_insul,:wall_base_cont_insul,:roof_base_cont_insul,:window_u,:window_shgc,:window_transmittance,:floor_base_cont_insul,:office_large_light_area,:kitchen_light_area,:dining_fast_light_area,:classroom_class_light_area,:corridor_light_area,:retail_sales_light_area,:storage_warehouse_light_area,:computer_light_area,:lobby_light_area,:guestroom_light_area,:auditorium_light_area,:conference_light_area,:dining_fine_light_area,:gym_light_area,:restroom_light_area,:health_patient_light_area,:industrial_low_light_area,:laundry_light_area,:auto_light_area,:classroom_shop_light_area,:grocery_light_area,:health_operating_light_area,:industrial_high_light_area,:lab_light_area,:mech_light_area,:office_open_light_area,:storage_refrig_light_area,:office_small_light_area,:main_oa_econ_max_temp,:cw_pump_min_flow_rate +#,Asm&0&cPVVE&Ex&Chiller__PumpCtrl,Asm/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""auditorium"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,ECC&0&cPVVE&Ex&Chiller__PumpCtrl,ECC/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""computer"", ""LPD"")['W/ft2']",,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""classroom_shop"", ""LPD"")['W/ft2']",,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate ECC"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,EPr&0&cPVVE&Ex&Chiller__PumpCtrl,EPr/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,"%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""gym"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,ERC&0&cPVVE&Ex&Chiller__PumpCtrl,ERC/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,"%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,ESe&0&cPVVE&Ex&Chiller__PumpCtrl,ESe/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,"%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""computer"", ""LPD"")['W/ft2']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""gym"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate ESe"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +,EUn&0&cPVVE&Ex&Chiller__PumpCtrl,EUn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""computer"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""guestroom"", ""LPD"")['W/ft2']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""industrial_low"", ""LPD"")['W/ft2']",,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate EUn"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,Fin&0&cPVVE&Ex&Chiller__PumpCtrl,Fin/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,,"%= codes.lookup(""Lighting Power Density"", ""retail_sales"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Gro&0&cPVVE&Ex&Chiller__PumpCtrl,Gro/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""grocery"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""industrial_high"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""storage_refrig"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,Hsp/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']",,,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""health_patient"", ""LPD"")['W/ft2']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""health_operating"", ""LPD"")['W/ft2']",,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate Hsp"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,Htl&0&cPVVE&Ex&Chiller__PumpCtrl,Htl/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""lobby"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""guestroom"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""dining_fine"", ""LPD"")['W/ft2']",,,,,"%= codes.lookup(""Lighting Power Density"", ""laundry"", ""LPD"")['W/ft2']",,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Lib&0&cPVVE&Ex&Chiller__PumpCtrl,Lib/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""retail_sales"", ""LPD"")['W/ft2']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""conference"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,MBT&0&cPVVE&Ex&Chiller__PumpCtrl,MBT/templates/root.pxt,Metal Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""computer"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""conference"", ""LPD"")['W/ft2']",,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""lab"", ""LPD"")['W/ft2']",,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,MLI&0&cPVVE&Ex&Chiller__PumpCtrl,MLI/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""industrial_low"", ""LPD"")['W/ft2']",,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Mtl&0&cPVVE&Ex&Chiller__PumpCtrl,Mtl/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,,,"%= codes.lookup(""Lighting Power Density"", ""guestroom"", ""LPD"")['W/ft2']",,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""laundry"", ""LPD"")['W/ft2']",,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,Nrs/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""health_patient"", ""LPD"")['W/ft2']",,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate Nrs"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +,OfL&0&cPVVE&Ex&Chiller__PumpCtrl,OfL/templates/root.pxt,Metal Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""lobby"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""mech"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""office_open"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate OfL"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +,OfS&0&cPVVE&Ex&Chiller__PumpCtrl,OfS/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""office_small"", ""LPD"")['W/ft2']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate OfS"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,Rel&0&cPVVE&Ex&Chiller__PumpCtrl,Rel/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""auditorium"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RFF&0&cPVVE&Ex&Chiller__PumpCtrl,RFF/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,"%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""lobby"", ""LPD"")['W/ft2']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""restroom"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RSD&0&cPVVE&Ex&Chiller__PumpCtrl,RSD/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,"%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""lobby"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""dining_fine"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""restroom"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,Rt3/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""retail_sales"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate Rt3"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,RtL&0&cPVVE&Ex&Chiller__PumpCtrl,RtL/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""retail_sales"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""auto"", ""LPD"")['W/ft2']",,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RtS&0&cPVVE&Ex&Chiller__PumpCtrl,RtS/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""retail_sales"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,SCn&0&cPVVE&Ex&Chiller__PumpCtrl,SCn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,SUn&0&cPVVE&Ex&Chiller__PumpCtrl,SUn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,WRf,WRf/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/query.txt b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/query.txt new file mode 100644 index 00000000..f16ea16a --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/query.txt @@ -0,0 +1,32 @@ +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Site Energy, Net Site EUI +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Total Energy/Net Site Energy, Net Site Energy +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Source Energy, Net Source EUI +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Total Energy/Net Source Energy, Net Source Energy + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Total End Uses, Total +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heating, Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Cooling, Cooling +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Interior Lighting, Interior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Exterior Lighting, Exterior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Interior Equipment, Interior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Exterior Equipment, Exterior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Fans, Fans +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Pumps, Pumps +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heat Rejection, Heat Rejection +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Humidification, Humidification +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heat Recovery, Heat Recovery +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Water Systems, Water Systems +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Refrigeration, Refrigeration +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Generators, Generators +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Heating, Heating Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Cooling, Cooling Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Heating, Heating NG +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Cooling, Cooling NG +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Interior Equipment, Interior Equipment Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Interior Equipment, Interior Equipment NG + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Total End Uses, Electricity +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Total End Uses, Natural Gas + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Comfort and Setpoint Not Met Summary/Facility/Time Setpoint Not Met During Occupied Heating, Unmet Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Comfort and Setpoint Not Met Summary/Facility/Time Setpoint Not Met During Occupied Cooling, Unmet Cooling diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/renamed_cohort.xlsx b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/renamed_cohort.xlsx new file mode 100644 index 00000000..953b38d7 Binary files /dev/null and b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/renamed_cohort.xlsx differ diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/result.py b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/result.py new file mode 100644 index 00000000..32dde4ca --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Ex/result.py @@ -0,0 +1,361 @@ +#!/usr/bin/env python +# coding: utf-8 + +"""EnergyPlus batch results data scraping tool, based on modelkit. + +Features: +* Read from instance-out.sql files using result spec format like modelkit +* Outputs disaggregated and aggregated result files, to review individual component sizing +* Requires python >= 3.7.1 and additional package "tqdm" + +Usage: + Prerequisite: running models, select a query file + $terminal1> cd C:/DEER-Prototypes-EnergyPlus/ + $terminal1> python "scripts/result.py" "commercial measures/SWXX000-00 Measure Name" --queryfile "querylibrary/query_default.txt" --detailfile "commercial measures/SWXX000-00 Measure Name/results-sizing-detail.csv" --aggfile "commercial measures/SWXX000-00 Measure Name/results-sizing-agg.csv" + +Changelog + * 2024-01-19 Python script to enable updating query without re-running models + * 2024-02-08 Improve handling of string type results + * 2024-02-08 Handle comment lines and empty results + * 2024-02-09 Add argument to control show/hide of "runs" folder in File Name + * 2024-02-09 Fix dataframe get notation + +@Author: Nicholas Fette +@Date: 2023-11-05 + +""" + +##STEP 0: Setup (import all necessary libraries) +import re +from dataclasses import dataclass, asdict, astuple +from sqlite3 import connect +from pathlib import Path +from multiprocessing import Pool +from io import BytesIO + +import pandas as pd +from tqdm import tqdm, trange + +FILENAME_FINISHED = 'instance-out.sql' +TABULAR_DATA_HEADERS = ['ReportName', 'ReportForString', + 'TableName', 'ColumnName', 'RowName'] +TOKEN_ANY = '*' + +@dataclass +class ResultSpec(object): + ReportName: str + ReportForString: str + TableName: str + ColumnName: str + RowName: str + + def to_string(self): + return "{ReportName}/{ReportForString}/{TableName}/{ColumnName}/{RowName}".format(**asdict(self)) + +def makeResultSpec(specstr: str) -> ResultSpec: + fields = specstr.split('/') + return ResultSpec(*fields) + +def build_query(resultspec: ResultSpec, finalize = True) -> str: + if not isinstance(resultspec, ResultSpec): + resultspec = makeResultSpec(resultspec) + + agg_columns = ['ReportName'] + query = """SELECT * from TabularDataWithStrings + WHERE ReportName = :ReportName""" + + if (resultspec.ReportForString and resultspec.ReportForString != TOKEN_ANY): + query += " AND ReportForString = :ReportForString" + agg_columns.append('ReportForString') + + if (resultspec.TableName and resultspec.TableName != TOKEN_ANY): + query += " AND TableName = :TableName" + agg_columns.append('TableName') + + if (resultspec.ColumnName and resultspec.ColumnName != TOKEN_ANY): + query += " AND ColumnName = :ColumnName" + agg_columns.append('ColumnName') + + if (resultspec.RowName and resultspec.RowName != TOKEN_ANY): + query += " AND RowName = :RowName" + agg_columns.append('ReportForString') + + if finalize: + query += ";" + agg_columns.append('Units') + return query, agg_columns + +def get_a_result(sqlfile: Path, resultspec: ResultSpec, aggtype='sum') -> tuple: + + if not isinstance(resultspec, ResultSpec): + resultspec = makeResultSpec(resultspec) + + query,agg_columns = build_query(resultspec) + + if resultspec.to_string().startswith("AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/"): + # Special case. 'Total Energy' is a synthetic result not defined by EnergyPlus. + # It is not a good idea to use this because it is adding quantities with different meanings (kWh electric + kWh gas, etc). + if resultspec.RowName == TOKEN_ANY: + query,agg_columns = build_query( + "AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/*", + False) + query += """ AND ColumnName <> 'Water';""" + else: + query,agg_columns = build_query( + f"AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/{resultspec.RowName}", + False) + query += """ AND ColumnName <> 'Water';""" + + with connect(sqlfile) as conn: + try: + sim_sizing_data = pd.read_sql_query(query, conn, params=asdict(resultspec), dtype={'Value':float}) + except ValueError: + # If user requested a query that returns a string value + # To do: aggregation doesn't work with string type results. + sim_sizing_data = pd.read_sql_query(query, conn, params=asdict(resultspec)) + + if sim_sizing_data.empty: + # No data found matching result spec + return None, None + elif len(sim_sizing_data) == 1: + # Only one value, no aggregation required + return sim_sizing_data, sim_sizing_data.loc[0,'Value'] + else: + # Aggregation requested. Calculate a single float value. + sizing_agg = ( + sim_sizing_data + .groupby(agg_columns) + ['Value'].agg(aggtype).iloc[0] + ) + return sim_sizing_data, sizing_agg + +def gather_sizing_data1(subroot: Path, resultspec: ResultSpec, progressbar=False): + """ + Copy model files and hourly output files to a different folder. + + Assumes that files are placed within a "runs" subfolder. + + subroot: e.g., "C:\path\DEER-Prototypes-EnergyPlus\Analysis\SFm_Furnace_1975" + """ + + if progressbar: + from tqdm import tqdm + + if not isinstance(subroot, Path): + subroot = Path(subroot) + meas_group = subroot.name + + # Count composed models. + runs_root = subroot.joinpath('runs') + subroot_finished_list = list(runs_root.glob('**/'+FILENAME_FINISHED)) + n_models = len(subroot_finished_list) + + if progressbar: + # Create the progress bar here. + myiter = tqdm(subroot_finished_list, desc=subroot.name) + else: + myiter = subroot_finished_list + + sim_sizing_data, sizing_agg = [], [] + for sqlfile in myiter: + relpath = sqlfile.relative_to(subroot) + # E.g. relpath = CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\Msr-Res-GasFurnace-AFUE95-ECM\instance-out.sql + relstr = relpath.as_posix() # with forward slashes + # E.g. relpath = CZ01/SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace/Msr-Res-GasFurnace-AFUE95-ECM/instance-out.sql + + #_, cz, cohort, techid, _ = relpath.parts + #print(meas_group, cz, cohort, techid) + + a,b = get_a_result(sqlfile, resultspec) + a["File Name"] = relstr + + sim_sizing_data.append(a) + sizing_agg.append((relstr, b)) + + if progressbar: + myiter.close() + + sim_sizing_data = pd.concat(sim_sizing_data) + sizing_agg = pd.DataFrame(sizing_agg,columns=['File Name','Value']) + + return sim_sizing_data, sizing_agg + +def parse_query_file(queryfile: Path): + """Reads the query.txt file and returns a list of tuples (resultspec, name) + where + resultspec is a ResultSpec object + name is the name to assign to output. + + If name is ommitted in the query.txt, name will be like "ColumnName/RowName". + """ + if not isinstance(queryfile, Path): + queryfile = Path(queryfile) + + listlist_query_path_and_name = [] + list_query_path_and_name = [] + with queryfile.open() as f: + for query_line in f: + if query_line.isspace(): + if list_query_path_and_name != []: + listlist_query_path_and_name.append(list_query_path_and_name) + list_query_path_and_name = [] + continue + if query_line.startswith("#"): + continue + m = re.match(r'\s*(.+)\s*,\s*(.+)\s*',query_line) + if m: + query_path, user_column_name = m.groups() + resultspec = makeResultSpec(query_path) + else: + query_path = query_line.strip() + resultspec = makeResultSpec(query_path) + user_column_name = "{ColumnName}/{RowName}".format(**asdict(resultspec)) + list_query_path_and_name.append((resultspec, user_column_name)) + if list_query_path_and_name != []: + listlist_query_path_and_name.append(list_query_path_and_name) + return listlist_query_path_and_name + +def gather_sizing_data2(subroot: Path, queryfile: Path, progressbar=False, runspath='runs'): + r""" + Read selected data entries from SQL outputs and write to CSV. + Result set specifications are parsed from query.txt, e.g. (resultspec, name). + Output columns will have units appended to name, like "name (Units)". + + Assumes that files are placed within a "runs" subfolder under the given subroot. + + subroot: e.g., "C:\Users\User1\DEER-Prototypes-EnergyPlus\Analysis\SFm_Furnace_1975" + """ + + if progressbar: + from tqdm import tqdm + + if not isinstance(subroot, Path): + subroot = Path(subroot) + meas_group = subroot.name + + listlist_query_path_and_name = parse_query_file(queryfile) + + result_sets = [] + for list_query_path_and_name in listlist_query_path_and_name: + columns_out = ['File Name'] + [name for _,name in list_query_path_and_name] + + # Count composed models. + runs_root = subroot.joinpath(runspath) + subroot_finished_list = list(runs_root.glob('**/'+FILENAME_FINISHED)) + n_models = len(subroot_finished_list) + + if progressbar: + # Create the progress bar here. + myiter = tqdm(subroot_finished_list, desc=subroot.name) + else: + myiter = subroot_finished_list + + sim_sizing_data, sizing_agg = [], [] + for sqlfile in myiter: + relpath = sqlfile.relative_to(runs_root) + # E.g. relpath = Path(r"CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\Msr-Res-GasFurnace-AFUE95-ECM\instance-out.sql") + relstr = relpath.as_posix() # with forward slashes + # E.g. relstr = "CZ01/SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace/Msr-Res-GasFurnace-AFUE95-ECM/instance-out.sql" + #_, cz, cohort, techid, _ = relpath.parts + #print(meas_group, cz, cohort, techid) + + sizing_agg_row = {"File Name": relstr} + for resultspec, user_column_name in list_query_path_and_name: + a,b = get_a_result(sqlfile, resultspec) + if a is None: + # No data found matching the result spec. Skip this and go to next. + continue + a["File Name"] = relstr + units = a['Units'].iloc[0] + sim_sizing_data.append(a) + sizing_agg_row.update({f"{user_column_name} ({units})": b}) + sizing_agg.append(sizing_agg_row) + + if progressbar: + myiter.close() + + sim_sizing_data = pd.concat(sim_sizing_data) + sizing_agg = pd.DataFrame(sizing_agg) + result_sets.append((sim_sizing_data, sizing_agg)) + + return result_sets + +def main(): + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('subroot', type=Path, default='.', + help=r'Analysis subfolder, e.g. C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975') + parser.add_argument('-q','--queryfile', type=Path, default='query.txt', + help=r'Query file, e.g. query.txt') + parser.add_argument('-d','--detailfile', type=Path, default='results-sizing-detail.csv', + help=r'Output file for detailed sizing info, e.g. results-sizing-detail.csv') + parser.add_argument('-a','--aggfile', type=Path, default='results-sizing-agg.csv', + help=r'Output file for aggregated sizing info, e.g. results-sizing-agg.csv') + parser.add_argument('-r','--runspath', type=str, default='runs', + help=r'Path within study folder to omit from "File Name" output column.') + + pargs = parser.parse_args() + result_sets = gather_sizing_data2(pargs.subroot, pargs.queryfile, True, pargs.runspath) + + output1 = BytesIO() + output2 = BytesIO() + + for sim_sizing_data, sizing_agg in result_sets: + sim_sizing_data.to_csv(output1,mode='a',index=False) + output1.write(b'\r\n') + sizing_agg.to_csv(output2,mode='a',index=False) + output2.write(b'\r\n') + + pargs.detailfile.write_bytes(output1.getbuffer()) + pargs.aggfile.write_bytes(output2.getbuffer()) + +def test1(): + specstr = "AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Site Energy" + sqlfile = r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975\runs\CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\AFUE_80_baseline\instance-out.sql" + myspec = makeResultSpec(specstr) + print(myspec) + sim_sizing_data, sizing_agg = get_a_result(sqlfile, myspec) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test2(): + specstr = "ComponentSizingSummary/Entire Facility/Coil:Heating:Fuel/Design Size Nominal Capacity/*" + sqlfile = r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975\runs\CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\AFUE_80_baseline\instance-out.sql" + myspec = makeResultSpec(specstr) + sim_sizing_data, sizing_agg = get_a_result(sqlfile, myspec) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test3(): + sim_sizing_data, sizing_agg = gather_sizing_data1( + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975", + "ComponentSizingSummary/Entire Facility/Coil:Heating:Fuel/Design Size Nominal Capacity/*", + True) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test4(): + result_sets = gather_sizing_data2( + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975", + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\DMo_Brushless_Fan_Motor_Ex\query.txt", + True) + for sim_sizing_data, sizing_agg in result_sets: + print(sim_sizing_data) + print(sizing_agg) + sim_sizing_data.to_csv('results-sim-sizing.csv',mode='a',index=False) + sizing_agg.to_csv('results-sizing-agg.csv',mode='a',index=False) + return result_sets + +def test_all(): + #sim_sizing_data, sizing_agg = test1() + #sim_sizing_data, sizing_agg = test2() + #sim_sizing_data, sizing_agg = test3() + result_set = test4() + print("Done.") + +if "__main__" == __name__: + #test_all() + main() diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/cases/Htl&0&cPVVE&Ex&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/cases/Htl&0&cPVVE&Ex&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/cases/Htl&0&cPVVE&Ex&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/climates.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/climates.csv new file mode 100644 index 00000000..9f5cc7a8 --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/climates.csv @@ -0,0 +1,17 @@ +skip,climate,weather_file,climate_zone,codes_file +,CZ01,CA_EUREKA_725940S_CZ2022.epw,1,T24_weight_averaged_ex_Htl.csv +,CZ02,CA_NAPA-CO_724955S_CZ2022.epw,2,T24_weight_averaged_ex_Htl.csv +,CZ03,CA_OAKLAND-METRO-AP_724930S_CZ2022.epw,3,T24_weight_averaged_ex_Htl.csv +,CZ04,CA_SAN-JOSE-IAP_724945S_CZ2022.epw,4,T24_weight_averaged_ex_Htl.csv +,CZ05,CA_SANTA-MARIA-PUBLIC-AP_723940S_CZ2022.epw,5,T24_weight_averaged_ex_Htl.csv +,CZ06,CA_LOS-ANGELES-IAP_722950S_CZ2022.epw,6,T24_weight_averaged_ex_Htl.csv +,CZ07,CA_SAN-DIEGO-LINDBERGH-FLD_722900S_CZ2022.epw,7,T24_weight_averaged_ex_Htl.csv +,CZ08,CA_LONG-BEACH-DAUGHERTY-FLD_722970S_CZ2022.epw,8,T24_weight_averaged_ex_Htl.csv +,CZ09,CA_LOS-ANGELES-DOWNTOWN-USC_722874S_CZ2022.epw,9,T24_weight_averaged_ex_Htl.csv +,CZ10,CA_RIVERSIDE-MUNI_722869S_CZ2022.epw,10,T24_weight_averaged_ex_Htl.csv +,CZ11,CA_RED-BLUFF-MUNI-AP_725910S_CZ2022.epw,11,T24_weight_averaged_ex_Htl.csv +,CZ12,CA_STOCKTON-METRO-AP_724920S_CZ2022.epw,12,T24_weight_averaged_ex_Htl.csv +,CZ13,CA_FRESNO-YOSEMITE-IAP_723890S_CZ2022.epw,13,T24_weight_averaged_ex_Htl.csv +,CZ14,CA_DAGGETT-BARSTOW-AP_723815S_CZ2022.epw,14,T24_weight_averaged_ex_Htl.csv +,CZ15,CA_EL-CENTRO-NAF_722810S_CZ2022.epw,15,T24_weight_averaged_ex_Htl.csv +,CZ16,CA_BISHOP-AP_724800S_CZ2022.epw,16,T24_weight_averaged_ex_Htl.csv diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/cohorts.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/cohorts.csv new file mode 100644 index 00000000..428bb73c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/cohorts.csv @@ -0,0 +1,26 @@ +skip,cohort,root,wall_type,:wall_base_cavity_insul,:wall_base_cont_insul,:roof_base_cont_insul,:window_u,:window_shgc,:window_transmittance,:floor_base_cont_insul,:main_oa_econ_max_temp,:cw_pump_min_flow_rate +#,Asm&0&cPVVE&Ex&Chiller__PumpCtrl,Asm/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,ECC&0&cPVVE&Ex&Chiller__PumpCtrl,ECC/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,EPr&0&cPVVE&Ex&Chiller__PumpCtrl,EPr/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,ERC&0&cPVVE&Ex&Chiller__PumpCtrl,ERC/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,ESe&0&cPVVE&Ex&Chiller__PumpCtrl,ESe/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,EUn&0&cPVVE&Ex&Chiller__PumpCtrl,EUn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Fin&0&cPVVE&Ex&Chiller__PumpCtrl,Fin/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Gro&0&cPVVE&Ex&Chiller__PumpCtrl,Gro/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,Hsp/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,Htl&0&cPVVE&Ex&Chiller__PumpCtrl,Htl/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate Htl"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,Lib&0&cPVVE&Ex&Chiller__PumpCtrl,Lib/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,MBT&0&cPVVE&Ex&Chiller__PumpCtrl,MBT/templates/root.pxt,Metal Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,MLI&0&cPVVE&Ex&Chiller__PumpCtrl,MLI/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Mtl&0&cPVVE&Ex&Chiller__PumpCtrl,Mtl/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,Nrs/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,OfL&0&cPVVE&Ex&Chiller__PumpCtrl,OfL/templates/root.pxt,Metal Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,OfS&0&cPVVE&Ex&Chiller__PumpCtrl,OfS/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Rel&0&cPVVE&Ex&Chiller__PumpCtrl,Rel/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RFF&0&cPVVE&Ex&Chiller__PumpCtrl,RFF/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RSD&0&cPVVE&Ex&Chiller__PumpCtrl,RSD/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,Rt3/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RtL&0&cPVVE&Ex&Chiller__PumpCtrl,RtL/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RtS&0&cPVVE&Ex&Chiller__PumpCtrl,RtS/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,SCn&0&cPVVE&Ex&Chiller__PumpCtrl,SCn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,SUn&0&cPVVE&Ex&Chiller__PumpCtrl,SUn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/query.txt b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/query.txt new file mode 100644 index 00000000..f16ea16a --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/query.txt @@ -0,0 +1,32 @@ +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Site Energy, Net Site EUI +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Total Energy/Net Site Energy, Net Site Energy +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Source Energy, Net Source EUI +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Total Energy/Net Source Energy, Net Source Energy + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Total End Uses, Total +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heating, Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Cooling, Cooling +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Interior Lighting, Interior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Exterior Lighting, Exterior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Interior Equipment, Interior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Exterior Equipment, Exterior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Fans, Fans +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Pumps, Pumps +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heat Rejection, Heat Rejection +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Humidification, Humidification +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heat Recovery, Heat Recovery +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Water Systems, Water Systems +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Refrigeration, Refrigeration +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Generators, Generators +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Heating, Heating Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Cooling, Cooling Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Heating, Heating NG +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Cooling, Cooling NG +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Interior Equipment, Interior Equipment Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Interior Equipment, Interior Equipment NG + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Total End Uses, Electricity +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Total End Uses, Natural Gas + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Comfort and Setpoint Not Met Summary/Facility/Time Setpoint Not Met During Occupied Heating, Unmet Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Comfort and Setpoint Not Met Summary/Facility/Time Setpoint Not Met During Occupied Cooling, Unmet Cooling diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/renamed_cohort.xlsx b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/renamed_cohort.xlsx new file mode 100644 index 00000000..953b38d7 Binary files /dev/null and b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/renamed_cohort.xlsx differ diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/result.py b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/result.py new file mode 100644 index 00000000..32dde4ca --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_Ex/result.py @@ -0,0 +1,361 @@ +#!/usr/bin/env python +# coding: utf-8 + +"""EnergyPlus batch results data scraping tool, based on modelkit. + +Features: +* Read from instance-out.sql files using result spec format like modelkit +* Outputs disaggregated and aggregated result files, to review individual component sizing +* Requires python >= 3.7.1 and additional package "tqdm" + +Usage: + Prerequisite: running models, select a query file + $terminal1> cd C:/DEER-Prototypes-EnergyPlus/ + $terminal1> python "scripts/result.py" "commercial measures/SWXX000-00 Measure Name" --queryfile "querylibrary/query_default.txt" --detailfile "commercial measures/SWXX000-00 Measure Name/results-sizing-detail.csv" --aggfile "commercial measures/SWXX000-00 Measure Name/results-sizing-agg.csv" + +Changelog + * 2024-01-19 Python script to enable updating query without re-running models + * 2024-02-08 Improve handling of string type results + * 2024-02-08 Handle comment lines and empty results + * 2024-02-09 Add argument to control show/hide of "runs" folder in File Name + * 2024-02-09 Fix dataframe get notation + +@Author: Nicholas Fette +@Date: 2023-11-05 + +""" + +##STEP 0: Setup (import all necessary libraries) +import re +from dataclasses import dataclass, asdict, astuple +from sqlite3 import connect +from pathlib import Path +from multiprocessing import Pool +from io import BytesIO + +import pandas as pd +from tqdm import tqdm, trange + +FILENAME_FINISHED = 'instance-out.sql' +TABULAR_DATA_HEADERS = ['ReportName', 'ReportForString', + 'TableName', 'ColumnName', 'RowName'] +TOKEN_ANY = '*' + +@dataclass +class ResultSpec(object): + ReportName: str + ReportForString: str + TableName: str + ColumnName: str + RowName: str + + def to_string(self): + return "{ReportName}/{ReportForString}/{TableName}/{ColumnName}/{RowName}".format(**asdict(self)) + +def makeResultSpec(specstr: str) -> ResultSpec: + fields = specstr.split('/') + return ResultSpec(*fields) + +def build_query(resultspec: ResultSpec, finalize = True) -> str: + if not isinstance(resultspec, ResultSpec): + resultspec = makeResultSpec(resultspec) + + agg_columns = ['ReportName'] + query = """SELECT * from TabularDataWithStrings + WHERE ReportName = :ReportName""" + + if (resultspec.ReportForString and resultspec.ReportForString != TOKEN_ANY): + query += " AND ReportForString = :ReportForString" + agg_columns.append('ReportForString') + + if (resultspec.TableName and resultspec.TableName != TOKEN_ANY): + query += " AND TableName = :TableName" + agg_columns.append('TableName') + + if (resultspec.ColumnName and resultspec.ColumnName != TOKEN_ANY): + query += " AND ColumnName = :ColumnName" + agg_columns.append('ColumnName') + + if (resultspec.RowName and resultspec.RowName != TOKEN_ANY): + query += " AND RowName = :RowName" + agg_columns.append('ReportForString') + + if finalize: + query += ";" + agg_columns.append('Units') + return query, agg_columns + +def get_a_result(sqlfile: Path, resultspec: ResultSpec, aggtype='sum') -> tuple: + + if not isinstance(resultspec, ResultSpec): + resultspec = makeResultSpec(resultspec) + + query,agg_columns = build_query(resultspec) + + if resultspec.to_string().startswith("AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/"): + # Special case. 'Total Energy' is a synthetic result not defined by EnergyPlus. + # It is not a good idea to use this because it is adding quantities with different meanings (kWh electric + kWh gas, etc). + if resultspec.RowName == TOKEN_ANY: + query,agg_columns = build_query( + "AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/*", + False) + query += """ AND ColumnName <> 'Water';""" + else: + query,agg_columns = build_query( + f"AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/{resultspec.RowName}", + False) + query += """ AND ColumnName <> 'Water';""" + + with connect(sqlfile) as conn: + try: + sim_sizing_data = pd.read_sql_query(query, conn, params=asdict(resultspec), dtype={'Value':float}) + except ValueError: + # If user requested a query that returns a string value + # To do: aggregation doesn't work with string type results. + sim_sizing_data = pd.read_sql_query(query, conn, params=asdict(resultspec)) + + if sim_sizing_data.empty: + # No data found matching result spec + return None, None + elif len(sim_sizing_data) == 1: + # Only one value, no aggregation required + return sim_sizing_data, sim_sizing_data.loc[0,'Value'] + else: + # Aggregation requested. Calculate a single float value. + sizing_agg = ( + sim_sizing_data + .groupby(agg_columns) + ['Value'].agg(aggtype).iloc[0] + ) + return sim_sizing_data, sizing_agg + +def gather_sizing_data1(subroot: Path, resultspec: ResultSpec, progressbar=False): + """ + Copy model files and hourly output files to a different folder. + + Assumes that files are placed within a "runs" subfolder. + + subroot: e.g., "C:\path\DEER-Prototypes-EnergyPlus\Analysis\SFm_Furnace_1975" + """ + + if progressbar: + from tqdm import tqdm + + if not isinstance(subroot, Path): + subroot = Path(subroot) + meas_group = subroot.name + + # Count composed models. + runs_root = subroot.joinpath('runs') + subroot_finished_list = list(runs_root.glob('**/'+FILENAME_FINISHED)) + n_models = len(subroot_finished_list) + + if progressbar: + # Create the progress bar here. + myiter = tqdm(subroot_finished_list, desc=subroot.name) + else: + myiter = subroot_finished_list + + sim_sizing_data, sizing_agg = [], [] + for sqlfile in myiter: + relpath = sqlfile.relative_to(subroot) + # E.g. relpath = CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\Msr-Res-GasFurnace-AFUE95-ECM\instance-out.sql + relstr = relpath.as_posix() # with forward slashes + # E.g. relpath = CZ01/SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace/Msr-Res-GasFurnace-AFUE95-ECM/instance-out.sql + + #_, cz, cohort, techid, _ = relpath.parts + #print(meas_group, cz, cohort, techid) + + a,b = get_a_result(sqlfile, resultspec) + a["File Name"] = relstr + + sim_sizing_data.append(a) + sizing_agg.append((relstr, b)) + + if progressbar: + myiter.close() + + sim_sizing_data = pd.concat(sim_sizing_data) + sizing_agg = pd.DataFrame(sizing_agg,columns=['File Name','Value']) + + return sim_sizing_data, sizing_agg + +def parse_query_file(queryfile: Path): + """Reads the query.txt file and returns a list of tuples (resultspec, name) + where + resultspec is a ResultSpec object + name is the name to assign to output. + + If name is ommitted in the query.txt, name will be like "ColumnName/RowName". + """ + if not isinstance(queryfile, Path): + queryfile = Path(queryfile) + + listlist_query_path_and_name = [] + list_query_path_and_name = [] + with queryfile.open() as f: + for query_line in f: + if query_line.isspace(): + if list_query_path_and_name != []: + listlist_query_path_and_name.append(list_query_path_and_name) + list_query_path_and_name = [] + continue + if query_line.startswith("#"): + continue + m = re.match(r'\s*(.+)\s*,\s*(.+)\s*',query_line) + if m: + query_path, user_column_name = m.groups() + resultspec = makeResultSpec(query_path) + else: + query_path = query_line.strip() + resultspec = makeResultSpec(query_path) + user_column_name = "{ColumnName}/{RowName}".format(**asdict(resultspec)) + list_query_path_and_name.append((resultspec, user_column_name)) + if list_query_path_and_name != []: + listlist_query_path_and_name.append(list_query_path_and_name) + return listlist_query_path_and_name + +def gather_sizing_data2(subroot: Path, queryfile: Path, progressbar=False, runspath='runs'): + r""" + Read selected data entries from SQL outputs and write to CSV. + Result set specifications are parsed from query.txt, e.g. (resultspec, name). + Output columns will have units appended to name, like "name (Units)". + + Assumes that files are placed within a "runs" subfolder under the given subroot. + + subroot: e.g., "C:\Users\User1\DEER-Prototypes-EnergyPlus\Analysis\SFm_Furnace_1975" + """ + + if progressbar: + from tqdm import tqdm + + if not isinstance(subroot, Path): + subroot = Path(subroot) + meas_group = subroot.name + + listlist_query_path_and_name = parse_query_file(queryfile) + + result_sets = [] + for list_query_path_and_name in listlist_query_path_and_name: + columns_out = ['File Name'] + [name for _,name in list_query_path_and_name] + + # Count composed models. + runs_root = subroot.joinpath(runspath) + subroot_finished_list = list(runs_root.glob('**/'+FILENAME_FINISHED)) + n_models = len(subroot_finished_list) + + if progressbar: + # Create the progress bar here. + myiter = tqdm(subroot_finished_list, desc=subroot.name) + else: + myiter = subroot_finished_list + + sim_sizing_data, sizing_agg = [], [] + for sqlfile in myiter: + relpath = sqlfile.relative_to(runs_root) + # E.g. relpath = Path(r"CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\Msr-Res-GasFurnace-AFUE95-ECM\instance-out.sql") + relstr = relpath.as_posix() # with forward slashes + # E.g. relstr = "CZ01/SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace/Msr-Res-GasFurnace-AFUE95-ECM/instance-out.sql" + #_, cz, cohort, techid, _ = relpath.parts + #print(meas_group, cz, cohort, techid) + + sizing_agg_row = {"File Name": relstr} + for resultspec, user_column_name in list_query_path_and_name: + a,b = get_a_result(sqlfile, resultspec) + if a is None: + # No data found matching the result spec. Skip this and go to next. + continue + a["File Name"] = relstr + units = a['Units'].iloc[0] + sim_sizing_data.append(a) + sizing_agg_row.update({f"{user_column_name} ({units})": b}) + sizing_agg.append(sizing_agg_row) + + if progressbar: + myiter.close() + + sim_sizing_data = pd.concat(sim_sizing_data) + sizing_agg = pd.DataFrame(sizing_agg) + result_sets.append((sim_sizing_data, sizing_agg)) + + return result_sets + +def main(): + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('subroot', type=Path, default='.', + help=r'Analysis subfolder, e.g. C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975') + parser.add_argument('-q','--queryfile', type=Path, default='query.txt', + help=r'Query file, e.g. query.txt') + parser.add_argument('-d','--detailfile', type=Path, default='results-sizing-detail.csv', + help=r'Output file for detailed sizing info, e.g. results-sizing-detail.csv') + parser.add_argument('-a','--aggfile', type=Path, default='results-sizing-agg.csv', + help=r'Output file for aggregated sizing info, e.g. results-sizing-agg.csv') + parser.add_argument('-r','--runspath', type=str, default='runs', + help=r'Path within study folder to omit from "File Name" output column.') + + pargs = parser.parse_args() + result_sets = gather_sizing_data2(pargs.subroot, pargs.queryfile, True, pargs.runspath) + + output1 = BytesIO() + output2 = BytesIO() + + for sim_sizing_data, sizing_agg in result_sets: + sim_sizing_data.to_csv(output1,mode='a',index=False) + output1.write(b'\r\n') + sizing_agg.to_csv(output2,mode='a',index=False) + output2.write(b'\r\n') + + pargs.detailfile.write_bytes(output1.getbuffer()) + pargs.aggfile.write_bytes(output2.getbuffer()) + +def test1(): + specstr = "AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Site Energy" + sqlfile = r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975\runs\CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\AFUE_80_baseline\instance-out.sql" + myspec = makeResultSpec(specstr) + print(myspec) + sim_sizing_data, sizing_agg = get_a_result(sqlfile, myspec) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test2(): + specstr = "ComponentSizingSummary/Entire Facility/Coil:Heating:Fuel/Design Size Nominal Capacity/*" + sqlfile = r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975\runs\CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\AFUE_80_baseline\instance-out.sql" + myspec = makeResultSpec(specstr) + sim_sizing_data, sizing_agg = get_a_result(sqlfile, myspec) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test3(): + sim_sizing_data, sizing_agg = gather_sizing_data1( + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975", + "ComponentSizingSummary/Entire Facility/Coil:Heating:Fuel/Design Size Nominal Capacity/*", + True) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test4(): + result_sets = gather_sizing_data2( + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975", + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\DMo_Brushless_Fan_Motor_Ex\query.txt", + True) + for sim_sizing_data, sizing_agg in result_sets: + print(sim_sizing_data) + print(sizing_agg) + sim_sizing_data.to_csv('results-sim-sizing.csv',mode='a',index=False) + sizing_agg.to_csv('results-sizing-agg.csv',mode='a',index=False) + return result_sets + +def test_all(): + #sim_sizing_data, sizing_agg = test1() + #sim_sizing_data, sizing_agg = test2() + #sim_sizing_data, sizing_agg = test3() + result_set = test4() + print("Done.") + +if "__main__" == __name__: + #test_all() + main() diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/cases/Htl&0&cPVVE&New&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/cases/Htl&0&cPVVE&New&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/cases/Htl&0&cPVVE&New&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/climates.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/climates.csv new file mode 100644 index 00000000..14f1e59a --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/climates.csv @@ -0,0 +1,17 @@ +skip,climate,weather_file,climate_zone,codes_file +,CZ01,CA_EUREKA_725940S_CZ2022.epw,1,T24_2025_new_Htl.csv +,CZ02,CA_NAPA-CO_724955S_CZ2022.epw,2,T24_2025_new_Htl.csv +,CZ03,CA_OAKLAND-METRO-AP_724930S_CZ2022.epw,3,T24_2025_new_Htl.csv +,CZ04,CA_SAN-JOSE-IAP_724945S_CZ2022.epw,4,T24_2025_new_Htl.csv +,CZ05,CA_SANTA-MARIA-PUBLIC-AP_723940S_CZ2022.epw,5,T24_2025_new_Htl.csv +,CZ06,CA_LOS-ANGELES-IAP_722950S_CZ2022.epw,6,T24_2025_new_Htl.csv +,CZ07,CA_SAN-DIEGO-LINDBERGH-FLD_722900S_CZ2022.epw,7,T24_2025_new_Htl.csv +,CZ08,CA_LONG-BEACH-DAUGHERTY-FLD_722970S_CZ2022.epw,8,T24_2025_new_Htl.csv +,CZ09,CA_LOS-ANGELES-DOWNTOWN-USC_722874S_CZ2022.epw,9,T24_2025_new_Htl.csv +,CZ10,CA_RIVERSIDE-MUNI_722869S_CZ2022.epw,10,T24_2025_new_Htl.csv +,CZ11,CA_RED-BLUFF-MUNI-AP_725910S_CZ2022.epw,11,T24_2025_new_Htl.csv +,CZ12,CA_STOCKTON-METRO-AP_724920S_CZ2022.epw,12,T24_2025_new_Htl.csv +,CZ13,CA_FRESNO-YOSEMITE-IAP_723890S_CZ2022.epw,13,T24_2025_new_Htl.csv +,CZ14,CA_DAGGETT-BARSTOW-AP_723815S_CZ2022.epw,14,T24_2025_new_Htl.csv +,CZ15,CA_EL-CENTRO-NAF_722810S_CZ2022.epw,15,T24_2025_new_Htl.csv +,CZ16,CA_BISHOP-AP_724800S_CZ2022.epw,16,T24_2025_new_Htl.csv diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/cohorts.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/cohorts.csv new file mode 100644 index 00000000..1cc05f7c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/cohorts.csv @@ -0,0 +1,26 @@ +skip,cohort,root,wall_type,:wall_base_cavity_insul,:wall_base_cont_insul,:roof_base_cont_insul,:window_u,:window_shgc,:window_transmittance,:floor_base_cont_insul,:main_oa_econ_max_temp,:cw_pump_min_flow_rate +#,Asm&0&cPVVE&New&Chiller__PumpCtrl,Asm/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,ECC&0&cPVVE&New&Chiller__PumpCtrl,ECC/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,EPr&0&cPVVE&New&Chiller__PumpCtrl,EPr/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,ERC&0&cPVVE&New&Chiller__PumpCtrl,ERC/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,ESe&0&cPVVE&New&Chiller__PumpCtrl,ESe/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,EUn&0&cPVVE&New&Chiller__PumpCtrl,EUn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Fin&0&cPVVE&New&Chiller__PumpCtrl,Fin/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Gro&0&cPVVE&New&Chiller__PumpCtrl,Gro/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Hsp&0&cPVVE&New&Chiller__PumpCtrl,Hsp/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,Htl&0&cPVVE&New&Chiller__PumpCtrl,Htl/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate Htl"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,Lib&0&cPVVE&New&Chiller__PumpCtrl,Lib/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,MBT&0&cPVVE&New&Chiller__PumpCtrl,MBT/templates/root.pxt,Metal Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,MLI&0&cPVVE&New&Chiller__PumpCtrl,MLI/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Mtl&0&cPVVE&New&Chiller__PumpCtrl,Mtl/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Nrs&0&cPVVE&New&Chiller__PumpCtrl,Nrs/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,OfL&0&cPVVE&New&Chiller__PumpCtrl,OfL/templates/root.pxt,Metal Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,OfS&0&cPVVE&New&Chiller__PumpCtrl,OfS/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Rel&0&cPVVE&New&Chiller__PumpCtrl,Rel/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RFF&0&cPVVE&New&Chiller__PumpCtrl,RFF/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RSD&0&cPVVE&New&Chiller__PumpCtrl,RSD/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Rt3&0&cPVVE&New&Chiller__PumpCtrl,Rt3/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RtL&0&cPVVE&New&Chiller__PumpCtrl,RtL/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RtS&0&cPVVE&New&Chiller__PumpCtrl,RtS/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,SCn&0&cPVVE&New&Chiller__PumpCtrl,SCn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,SUn&0&cPVVE&New&Chiller__PumpCtrl,SUn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/query.txt b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/query.txt new file mode 100644 index 00000000..f16ea16a --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/query.txt @@ -0,0 +1,32 @@ +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Site Energy, Net Site EUI +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Total Energy/Net Site Energy, Net Site Energy +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Source Energy, Net Source EUI +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Total Energy/Net Source Energy, Net Source Energy + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Total End Uses, Total +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heating, Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Cooling, Cooling +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Interior Lighting, Interior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Exterior Lighting, Exterior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Interior Equipment, Interior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Exterior Equipment, Exterior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Fans, Fans +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Pumps, Pumps +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heat Rejection, Heat Rejection +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Humidification, Humidification +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heat Recovery, Heat Recovery +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Water Systems, Water Systems +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Refrigeration, Refrigeration +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Generators, Generators +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Heating, Heating Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Cooling, Cooling Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Heating, Heating NG +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Cooling, Cooling NG +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Interior Equipment, Interior Equipment Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Interior Equipment, Interior Equipment NG + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Total End Uses, Electricity +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Total End Uses, Natural Gas + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Comfort and Setpoint Not Met Summary/Facility/Time Setpoint Not Met During Occupied Heating, Unmet Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Comfort and Setpoint Not Met Summary/Facility/Time Setpoint Not Met During Occupied Cooling, Unmet Cooling diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/renamed_cohort.xlsx b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/renamed_cohort.xlsx new file mode 100644 index 00000000..b34e0483 Binary files /dev/null and b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/renamed_cohort.xlsx differ diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/result.py b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/result.py new file mode 100644 index 00000000..32dde4ca --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_Htl_New/result.py @@ -0,0 +1,361 @@ +#!/usr/bin/env python +# coding: utf-8 + +"""EnergyPlus batch results data scraping tool, based on modelkit. + +Features: +* Read from instance-out.sql files using result spec format like modelkit +* Outputs disaggregated and aggregated result files, to review individual component sizing +* Requires python >= 3.7.1 and additional package "tqdm" + +Usage: + Prerequisite: running models, select a query file + $terminal1> cd C:/DEER-Prototypes-EnergyPlus/ + $terminal1> python "scripts/result.py" "commercial measures/SWXX000-00 Measure Name" --queryfile "querylibrary/query_default.txt" --detailfile "commercial measures/SWXX000-00 Measure Name/results-sizing-detail.csv" --aggfile "commercial measures/SWXX000-00 Measure Name/results-sizing-agg.csv" + +Changelog + * 2024-01-19 Python script to enable updating query without re-running models + * 2024-02-08 Improve handling of string type results + * 2024-02-08 Handle comment lines and empty results + * 2024-02-09 Add argument to control show/hide of "runs" folder in File Name + * 2024-02-09 Fix dataframe get notation + +@Author: Nicholas Fette +@Date: 2023-11-05 + +""" + +##STEP 0: Setup (import all necessary libraries) +import re +from dataclasses import dataclass, asdict, astuple +from sqlite3 import connect +from pathlib import Path +from multiprocessing import Pool +from io import BytesIO + +import pandas as pd +from tqdm import tqdm, trange + +FILENAME_FINISHED = 'instance-out.sql' +TABULAR_DATA_HEADERS = ['ReportName', 'ReportForString', + 'TableName', 'ColumnName', 'RowName'] +TOKEN_ANY = '*' + +@dataclass +class ResultSpec(object): + ReportName: str + ReportForString: str + TableName: str + ColumnName: str + RowName: str + + def to_string(self): + return "{ReportName}/{ReportForString}/{TableName}/{ColumnName}/{RowName}".format(**asdict(self)) + +def makeResultSpec(specstr: str) -> ResultSpec: + fields = specstr.split('/') + return ResultSpec(*fields) + +def build_query(resultspec: ResultSpec, finalize = True) -> str: + if not isinstance(resultspec, ResultSpec): + resultspec = makeResultSpec(resultspec) + + agg_columns = ['ReportName'] + query = """SELECT * from TabularDataWithStrings + WHERE ReportName = :ReportName""" + + if (resultspec.ReportForString and resultspec.ReportForString != TOKEN_ANY): + query += " AND ReportForString = :ReportForString" + agg_columns.append('ReportForString') + + if (resultspec.TableName and resultspec.TableName != TOKEN_ANY): + query += " AND TableName = :TableName" + agg_columns.append('TableName') + + if (resultspec.ColumnName and resultspec.ColumnName != TOKEN_ANY): + query += " AND ColumnName = :ColumnName" + agg_columns.append('ColumnName') + + if (resultspec.RowName and resultspec.RowName != TOKEN_ANY): + query += " AND RowName = :RowName" + agg_columns.append('ReportForString') + + if finalize: + query += ";" + agg_columns.append('Units') + return query, agg_columns + +def get_a_result(sqlfile: Path, resultspec: ResultSpec, aggtype='sum') -> tuple: + + if not isinstance(resultspec, ResultSpec): + resultspec = makeResultSpec(resultspec) + + query,agg_columns = build_query(resultspec) + + if resultspec.to_string().startswith("AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/"): + # Special case. 'Total Energy' is a synthetic result not defined by EnergyPlus. + # It is not a good idea to use this because it is adding quantities with different meanings (kWh electric + kWh gas, etc). + if resultspec.RowName == TOKEN_ANY: + query,agg_columns = build_query( + "AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/*", + False) + query += """ AND ColumnName <> 'Water';""" + else: + query,agg_columns = build_query( + f"AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/{resultspec.RowName}", + False) + query += """ AND ColumnName <> 'Water';""" + + with connect(sqlfile) as conn: + try: + sim_sizing_data = pd.read_sql_query(query, conn, params=asdict(resultspec), dtype={'Value':float}) + except ValueError: + # If user requested a query that returns a string value + # To do: aggregation doesn't work with string type results. + sim_sizing_data = pd.read_sql_query(query, conn, params=asdict(resultspec)) + + if sim_sizing_data.empty: + # No data found matching result spec + return None, None + elif len(sim_sizing_data) == 1: + # Only one value, no aggregation required + return sim_sizing_data, sim_sizing_data.loc[0,'Value'] + else: + # Aggregation requested. Calculate a single float value. + sizing_agg = ( + sim_sizing_data + .groupby(agg_columns) + ['Value'].agg(aggtype).iloc[0] + ) + return sim_sizing_data, sizing_agg + +def gather_sizing_data1(subroot: Path, resultspec: ResultSpec, progressbar=False): + """ + Copy model files and hourly output files to a different folder. + + Assumes that files are placed within a "runs" subfolder. + + subroot: e.g., "C:\path\DEER-Prototypes-EnergyPlus\Analysis\SFm_Furnace_1975" + """ + + if progressbar: + from tqdm import tqdm + + if not isinstance(subroot, Path): + subroot = Path(subroot) + meas_group = subroot.name + + # Count composed models. + runs_root = subroot.joinpath('runs') + subroot_finished_list = list(runs_root.glob('**/'+FILENAME_FINISHED)) + n_models = len(subroot_finished_list) + + if progressbar: + # Create the progress bar here. + myiter = tqdm(subroot_finished_list, desc=subroot.name) + else: + myiter = subroot_finished_list + + sim_sizing_data, sizing_agg = [], [] + for sqlfile in myiter: + relpath = sqlfile.relative_to(subroot) + # E.g. relpath = CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\Msr-Res-GasFurnace-AFUE95-ECM\instance-out.sql + relstr = relpath.as_posix() # with forward slashes + # E.g. relpath = CZ01/SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace/Msr-Res-GasFurnace-AFUE95-ECM/instance-out.sql + + #_, cz, cohort, techid, _ = relpath.parts + #print(meas_group, cz, cohort, techid) + + a,b = get_a_result(sqlfile, resultspec) + a["File Name"] = relstr + + sim_sizing_data.append(a) + sizing_agg.append((relstr, b)) + + if progressbar: + myiter.close() + + sim_sizing_data = pd.concat(sim_sizing_data) + sizing_agg = pd.DataFrame(sizing_agg,columns=['File Name','Value']) + + return sim_sizing_data, sizing_agg + +def parse_query_file(queryfile: Path): + """Reads the query.txt file and returns a list of tuples (resultspec, name) + where + resultspec is a ResultSpec object + name is the name to assign to output. + + If name is ommitted in the query.txt, name will be like "ColumnName/RowName". + """ + if not isinstance(queryfile, Path): + queryfile = Path(queryfile) + + listlist_query_path_and_name = [] + list_query_path_and_name = [] + with queryfile.open() as f: + for query_line in f: + if query_line.isspace(): + if list_query_path_and_name != []: + listlist_query_path_and_name.append(list_query_path_and_name) + list_query_path_and_name = [] + continue + if query_line.startswith("#"): + continue + m = re.match(r'\s*(.+)\s*,\s*(.+)\s*',query_line) + if m: + query_path, user_column_name = m.groups() + resultspec = makeResultSpec(query_path) + else: + query_path = query_line.strip() + resultspec = makeResultSpec(query_path) + user_column_name = "{ColumnName}/{RowName}".format(**asdict(resultspec)) + list_query_path_and_name.append((resultspec, user_column_name)) + if list_query_path_and_name != []: + listlist_query_path_and_name.append(list_query_path_and_name) + return listlist_query_path_and_name + +def gather_sizing_data2(subroot: Path, queryfile: Path, progressbar=False, runspath='runs'): + r""" + Read selected data entries from SQL outputs and write to CSV. + Result set specifications are parsed from query.txt, e.g. (resultspec, name). + Output columns will have units appended to name, like "name (Units)". + + Assumes that files are placed within a "runs" subfolder under the given subroot. + + subroot: e.g., "C:\Users\User1\DEER-Prototypes-EnergyPlus\Analysis\SFm_Furnace_1975" + """ + + if progressbar: + from tqdm import tqdm + + if not isinstance(subroot, Path): + subroot = Path(subroot) + meas_group = subroot.name + + listlist_query_path_and_name = parse_query_file(queryfile) + + result_sets = [] + for list_query_path_and_name in listlist_query_path_and_name: + columns_out = ['File Name'] + [name for _,name in list_query_path_and_name] + + # Count composed models. + runs_root = subroot.joinpath(runspath) + subroot_finished_list = list(runs_root.glob('**/'+FILENAME_FINISHED)) + n_models = len(subroot_finished_list) + + if progressbar: + # Create the progress bar here. + myiter = tqdm(subroot_finished_list, desc=subroot.name) + else: + myiter = subroot_finished_list + + sim_sizing_data, sizing_agg = [], [] + for sqlfile in myiter: + relpath = sqlfile.relative_to(runs_root) + # E.g. relpath = Path(r"CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\Msr-Res-GasFurnace-AFUE95-ECM\instance-out.sql") + relstr = relpath.as_posix() # with forward slashes + # E.g. relstr = "CZ01/SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace/Msr-Res-GasFurnace-AFUE95-ECM/instance-out.sql" + #_, cz, cohort, techid, _ = relpath.parts + #print(meas_group, cz, cohort, techid) + + sizing_agg_row = {"File Name": relstr} + for resultspec, user_column_name in list_query_path_and_name: + a,b = get_a_result(sqlfile, resultspec) + if a is None: + # No data found matching the result spec. Skip this and go to next. + continue + a["File Name"] = relstr + units = a['Units'].iloc[0] + sim_sizing_data.append(a) + sizing_agg_row.update({f"{user_column_name} ({units})": b}) + sizing_agg.append(sizing_agg_row) + + if progressbar: + myiter.close() + + sim_sizing_data = pd.concat(sim_sizing_data) + sizing_agg = pd.DataFrame(sizing_agg) + result_sets.append((sim_sizing_data, sizing_agg)) + + return result_sets + +def main(): + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('subroot', type=Path, default='.', + help=r'Analysis subfolder, e.g. C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975') + parser.add_argument('-q','--queryfile', type=Path, default='query.txt', + help=r'Query file, e.g. query.txt') + parser.add_argument('-d','--detailfile', type=Path, default='results-sizing-detail.csv', + help=r'Output file for detailed sizing info, e.g. results-sizing-detail.csv') + parser.add_argument('-a','--aggfile', type=Path, default='results-sizing-agg.csv', + help=r'Output file for aggregated sizing info, e.g. results-sizing-agg.csv') + parser.add_argument('-r','--runspath', type=str, default='runs', + help=r'Path within study folder to omit from "File Name" output column.') + + pargs = parser.parse_args() + result_sets = gather_sizing_data2(pargs.subroot, pargs.queryfile, True, pargs.runspath) + + output1 = BytesIO() + output2 = BytesIO() + + for sim_sizing_data, sizing_agg in result_sets: + sim_sizing_data.to_csv(output1,mode='a',index=False) + output1.write(b'\r\n') + sizing_agg.to_csv(output2,mode='a',index=False) + output2.write(b'\r\n') + + pargs.detailfile.write_bytes(output1.getbuffer()) + pargs.aggfile.write_bytes(output2.getbuffer()) + +def test1(): + specstr = "AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Site Energy" + sqlfile = r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975\runs\CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\AFUE_80_baseline\instance-out.sql" + myspec = makeResultSpec(specstr) + print(myspec) + sim_sizing_data, sizing_agg = get_a_result(sqlfile, myspec) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test2(): + specstr = "ComponentSizingSummary/Entire Facility/Coil:Heating:Fuel/Design Size Nominal Capacity/*" + sqlfile = r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975\runs\CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\AFUE_80_baseline\instance-out.sql" + myspec = makeResultSpec(specstr) + sim_sizing_data, sizing_agg = get_a_result(sqlfile, myspec) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test3(): + sim_sizing_data, sizing_agg = gather_sizing_data1( + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975", + "ComponentSizingSummary/Entire Facility/Coil:Heating:Fuel/Design Size Nominal Capacity/*", + True) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test4(): + result_sets = gather_sizing_data2( + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975", + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\DMo_Brushless_Fan_Motor_Ex\query.txt", + True) + for sim_sizing_data, sizing_agg in result_sets: + print(sim_sizing_data) + print(sizing_agg) + sim_sizing_data.to_csv('results-sim-sizing.csv',mode='a',index=False) + sizing_agg.to_csv('results-sizing-agg.csv',mode='a',index=False) + return result_sets + +def test_all(): + #sim_sizing_data, sizing_agg = test1() + #sim_sizing_data, sizing_agg = test2() + #sim_sizing_data, sizing_agg = test3() + result_set = test4() + print("Done.") + +if "__main__" == __name__: + #test_all() + main() diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/ECC&0&cPVVE&New&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/ECC&0&cPVVE&New&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/ECC&0&cPVVE&New&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/ESe&0&cPVVE&New&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/ESe&0&cPVVE&New&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/ESe&0&cPVVE&New&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/EUn&0&cPVVE&New&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/EUn&0&cPVVE&New&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/EUn&0&cPVVE&New&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/Hsp&0&cPVVE&New&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/Hsp&0&cPVVE&New&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/Hsp&0&cPVVE&New&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/Nrs&0&cPVVE&New&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/Nrs&0&cPVVE&New&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/Nrs&0&cPVVE&New&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/OfL&0&cPVVE&New&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/OfL&0&cPVVE&New&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/OfL&0&cPVVE&New&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/OfS&0&cPVVE&New&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/OfS&0&cPVVE&New&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/OfS&0&cPVVE&New&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/Rt3&0&cPVVE&New&Chiller__PumpCtrl.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/Rt3&0&cPVVE&New&Chiller__PumpCtrl.csv new file mode 100644 index 00000000..4ece093c --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cases/Rt3&0&cPVVE&New&Chiller__PumpCtrl.csv @@ -0,0 +1,8 @@ +skip,case_name,:main_cool_coil_type,:chw_pump_type,:chw_chiller_condenser,:cw_num_towers,:cw_pump_control_type,:cw_pump_type,:chw_chiller_model,:chw_cw_temp_ref,:cw_pump_min_flow_rate,:cw_min_flowrate_fraction +,NE-Chiller-PumpCtrl-Full-Std,WATER,CONSTANT,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,34.44,, +,NE-Chiller-CWPumpCtrl-Full-Msr,WATER,CONSTANT,WATERCOOLED,1,Intermittent,VARIABLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,NE-Chiller-CHWPumpCtrl-Full-Msr,WATER,VARIABLE,WATERCOOLED,1,Intermittent,SINGLESPEED,WC Centrifugal Default 90.1-2004,29.44,, +,,,,,,,,,,, +,,,,,,,,,,, +#,"""Column K"" is :cw_pump_min_flow_rate: taken from a lookup table in code files outside cases files.",,,,,,,,,, +#,"""Column L"" is :cw_min_flowrate_fraction: parameter is unused in current setup.",,,,,,,,,, diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/climates.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/climates.csv new file mode 100644 index 00000000..5b1f9662 --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/climates.csv @@ -0,0 +1,17 @@ +skip,climate,weather_file,climate_zone,codes_file +,CZ01,CA_EUREKA_725940S_CZ2022.epw,1,T24_2025_new.csv +,CZ02,CA_NAPA-CO_724955S_CZ2022.epw,2,T24_2025_new.csv +,CZ03,CA_OAKLAND-METRO-AP_724930S_CZ2022.epw,3,T24_2025_new.csv +,CZ04,CA_SAN-JOSE-IAP_724945S_CZ2022.epw,4,T24_2025_new.csv +,CZ05,CA_SANTA-MARIA-PUBLIC-AP_723940S_CZ2022.epw,5,T24_2025_new.csv +,CZ06,CA_LOS-ANGELES-IAP_722950S_CZ2022.epw,6,T24_2025_new.csv +,CZ07,CA_SAN-DIEGO-LINDBERGH-FLD_722900S_CZ2022.epw,7,T24_2025_new.csv +,CZ08,CA_LONG-BEACH-DAUGHERTY-FLD_722970S_CZ2022.epw,8,T24_2025_new.csv +,CZ09,CA_LOS-ANGELES-DOWNTOWN-USC_722874S_CZ2022.epw,9,T24_2025_new.csv +,CZ10,CA_RIVERSIDE-MUNI_722869S_CZ2022.epw,10,T24_2025_new.csv +,CZ11,CA_RED-BLUFF-MUNI-AP_725910S_CZ2022.epw,11,T24_2025_new.csv +,CZ12,CA_STOCKTON-METRO-AP_724920S_CZ2022.epw,12,T24_2025_new.csv +,CZ13,CA_FRESNO-YOSEMITE-IAP_723890S_CZ2022.epw,13,T24_2025_new.csv +,CZ14,CA_DAGGETT-BARSTOW-AP_723815S_CZ2022.epw,14,T24_2025_new.csv +,CZ15,CA_EL-CENTRO-NAF_722810S_CZ2022.epw,15,T24_2025_new.csv +,CZ16,CA_BISHOP-AP_724800S_CZ2022.epw,16,T24_2025_new.csv diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cohorts.csv b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cohorts.csv new file mode 100644 index 00000000..038becb5 --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/cohorts.csv @@ -0,0 +1,27 @@ +skip,cohort,root,wall_type,:wall_base_cavity_insul,:wall_base_cont_insul,:roof_base_cont_insul,:window_u,:window_shgc,:window_transmittance,:floor_base_cont_insul,:office_large_light_area,:kitchen_light_area,:dining_fast_light_area,:classroom_class_light_area,:corridor_light_area,:retail_sales_light_area,:storage_warehouse_light_area,:computer_light_area,:lobby_light_area,:guestroom_light_area,:auditorium_light_area,:conference_light_area,:dining_fine_light_area,:gym_light_area,:restroom_light_area,:health_patient_light_area,:industrial_low_light_area,:laundry_light_area,:auto_light_area,:classroom_shop_light_area,:grocery_light_area,:health_operating_light_area,:industrial_high_light_area,:lab_light_area,:mech_light_area,:office_open_light_area,:storage_refrig_light_area,:office_small_light_area,:main_oa_econ_max_temp,:cw_pump_min_flow_rate +#,Asm&0&cPVVE&New&Chiller__PumpCtrl,Asm/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""auditorium"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,ECC&0&cPVVE&New&Chiller__PumpCtrl,ECC/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""computer"", ""LPD"")['W/ft2']",,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""classroom_shop"", ""LPD"")['W/ft2']",,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate ECC"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,EPr&0&cPVVE&New&Chiller__PumpCtrl,EPr/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,"%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""gym"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,ERC&0&cPVVE&New&Chiller__PumpCtrl,ERC/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,"%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,ESe&0&cPVVE&New&Chiller__PumpCtrl,ESe/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,"%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""computer"", ""LPD"")['W/ft2']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""gym"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate ESe"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +,EUn&0&cPVVE&New&Chiller__PumpCtrl,EUn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""computer"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""guestroom"", ""LPD"")['W/ft2']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""industrial_low"", ""LPD"")['W/ft2']",,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate EUn"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,Fin&0&cPVVE&New&Chiller__PumpCtrl,Fin/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,,"%= codes.lookup(""Lighting Power Density"", ""retail_sales"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Gro&0&cPVVE&New&Chiller__PumpCtrl,Gro/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""grocery"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""industrial_high"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""storage_refrig"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,Hsp&0&cPVVE&New&Chiller__PumpCtrl,Hsp/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']",,,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""health_patient"", ""LPD"")['W/ft2']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""health_operating"", ""LPD"")['W/ft2']",,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate Hsp"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,Htl&0&cPVVE&New&Chiller__PumpCtrl,Htl/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""lobby"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""guestroom"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""dining_fine"", ""LPD"")['W/ft2']",,,,,"%= codes.lookup(""Lighting Power Density"", ""laundry"", ""LPD"")['W/ft2']",,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Lib&0&cPVVE&New&Chiller__PumpCtrl,Lib/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""retail_sales"", ""LPD"")['W/ft2']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""conference"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,MBT&0&cPVVE&New&Chiller__PumpCtrl,MBT/templates/root.pxt,Metal Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""computer"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""conference"", ""LPD"")['W/ft2']",,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""lab"", ""LPD"")['W/ft2']",,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,MLI&0&cPVVE&New&Chiller__PumpCtrl,MLI/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""industrial_low"", ""LPD"")['W/ft2']",,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,Mtl&0&cPVVE&New&Chiller__PumpCtrl,Mtl/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,,,"%= codes.lookup(""Lighting Power Density"", ""guestroom"", ""LPD"")['W/ft2']",,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""laundry"", ""LPD"")['W/ft2']",,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,Nrs&0&cPVVE&New&Chiller__PumpCtrl,Nrs/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""health_patient"", ""LPD"")['W/ft2']",,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate Nrs"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +,OfL&0&cPVVE&New&Chiller__PumpCtrl,OfL/templates/root.pxt,Metal Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""lobby"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""mech"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""office_open"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate OfL"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +,OfS&0&cPVVE&New&Chiller__PumpCtrl,OfS/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""corridor"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""office_small"", ""LPD"")['W/ft2']","%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate OfS"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,Rel&0&cPVVE&New&Chiller__PumpCtrl,Rel/templates/root.pxt,steel-frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']",,,"%= codes.lookup(""Lighting Power Density"", ""classroom_class"", ""LPD"")['W/ft2']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""auditorium"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RFF&0&cPVVE&New&Chiller__PumpCtrl,RFF/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,"%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""dining_fast"", ""LPD"")['W/ft2']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""lobby"", ""LPD"")['W/ft2']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""restroom"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RSD&0&cPVVE&New&Chiller__PumpCtrl,RSD/templates/root.pxt,Wood Frame,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Wood Framed and Other"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,"%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""lobby"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""dining_fine"", ""LPD"")['W/ft2']",,"%= codes.lookup(""Lighting Power Density"", ""restroom"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +,Rt3&0&cPVVE&New&Chiller__PumpCtrl,Rt3/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""retail_sales"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']","%= codes.lookup(""CW Pump Min Flow Rate Rt3"", ""#{climate_zone}"", ""CW Pump Min Flow Rate"")" +#,RtL&0&cPVVE&New&Chiller__PumpCtrl,RtL/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']","%= codes.lookup(""Lighting Power Density"", ""office_large"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""kitchen"", ""LPD"")['W/ft2']",,,,"%= codes.lookup(""Lighting Power Density"", ""retail_sales"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,,,"%= codes.lookup(""Lighting Power Density"", ""auto"", ""LPD"")['W/ft2']",,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,RtS&0&cPVVE&New&Chiller__PumpCtrl,RtS/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,"%= codes.lookup(""Lighting Power Density"", ""retail_sales"", ""LPD"")['W/ft2']","%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,SCn&0&cPVVE&New&Chiller__PumpCtrl,SCn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Metal Framed"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Metal Buildings"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,SUn&0&cPVVE&New&Chiller__PumpCtrl,SUn/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", +#,WRf,WRf/templates/root.pxt,Mass Heavy,"%= codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Cavity R-Value"")['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Walls Above Grade | Mass Heavy"", ""Maximum U-Factor"")-1.49)['R-IP']","%= (1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Roofs | Wood Framed and Other"", ""Maximum U-Factor"")-0.78)['R-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""U-Factor""))['U-IP']","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""SHGC""))","%= (codes.lookup(""Fenestration Requirements | Climate Zone #{climate_zone}"", ""Fixed Window"", ""VT""))","%= ((1/codes.lookup(""Opaque Envelope Requirements | Climate Zone #{climate_zone}"", ""Floors | Other"", ""Maximum U-Factor""))-4.261)['R-IP']",,,,,,,"%= codes.lookup(""Lighting Power Density"", ""storage_warehouse"", ""LPD"")['W/ft2']",,,,,,,,,,,,,,,,,,,,,,"%= codes.lookup(""Economizer Setpoints"", ""#{climate_zone}"", ""Fixed Drybulb"")['F']", diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/query.txt b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/query.txt new file mode 100644 index 00000000..f16ea16a --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/query.txt @@ -0,0 +1,32 @@ +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Site Energy, Net Site EUI +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Total Energy/Net Site Energy, Net Site Energy +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Source Energy, Net Source EUI +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Total Energy/Net Source Energy, Net Source Energy + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Total End Uses, Total +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heating, Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Cooling, Cooling +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Interior Lighting, Interior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Exterior Lighting, Exterior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Interior Equipment, Interior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Exterior Equipment, Exterior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Fans, Fans +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Pumps, Pumps +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heat Rejection, Heat Rejection +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Humidification, Humidification +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Heat Recovery, Heat Recovery +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Water Systems, Water Systems +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Refrigeration, Refrigeration +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/Generators, Generators +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Heating, Heating Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Cooling, Cooling Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Heating, Heating NG +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Cooling, Cooling NG +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Interior Equipment, Interior Equipment Elec +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Interior Equipment, Interior Equipment NG + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Total End Uses, Electricity +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Total End Uses, Natural Gas + +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Comfort and Setpoint Not Met Summary/Facility/Time Setpoint Not Met During Occupied Heating, Unmet Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Comfort and Setpoint Not Met Summary/Facility/Time Setpoint Not Met During Occupied Cooling, Unmet Cooling diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/renamed_cohort.xlsx b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/renamed_cohort.xlsx new file mode 100644 index 00000000..b34e0483 Binary files /dev/null and b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/renamed_cohort.xlsx differ diff --git a/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/result.py b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/result.py new file mode 100644 index 00000000..32dde4ca --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/SWHC008-04 VSD Central Plant_New/result.py @@ -0,0 +1,361 @@ +#!/usr/bin/env python +# coding: utf-8 + +"""EnergyPlus batch results data scraping tool, based on modelkit. + +Features: +* Read from instance-out.sql files using result spec format like modelkit +* Outputs disaggregated and aggregated result files, to review individual component sizing +* Requires python >= 3.7.1 and additional package "tqdm" + +Usage: + Prerequisite: running models, select a query file + $terminal1> cd C:/DEER-Prototypes-EnergyPlus/ + $terminal1> python "scripts/result.py" "commercial measures/SWXX000-00 Measure Name" --queryfile "querylibrary/query_default.txt" --detailfile "commercial measures/SWXX000-00 Measure Name/results-sizing-detail.csv" --aggfile "commercial measures/SWXX000-00 Measure Name/results-sizing-agg.csv" + +Changelog + * 2024-01-19 Python script to enable updating query without re-running models + * 2024-02-08 Improve handling of string type results + * 2024-02-08 Handle comment lines and empty results + * 2024-02-09 Add argument to control show/hide of "runs" folder in File Name + * 2024-02-09 Fix dataframe get notation + +@Author: Nicholas Fette +@Date: 2023-11-05 + +""" + +##STEP 0: Setup (import all necessary libraries) +import re +from dataclasses import dataclass, asdict, astuple +from sqlite3 import connect +from pathlib import Path +from multiprocessing import Pool +from io import BytesIO + +import pandas as pd +from tqdm import tqdm, trange + +FILENAME_FINISHED = 'instance-out.sql' +TABULAR_DATA_HEADERS = ['ReportName', 'ReportForString', + 'TableName', 'ColumnName', 'RowName'] +TOKEN_ANY = '*' + +@dataclass +class ResultSpec(object): + ReportName: str + ReportForString: str + TableName: str + ColumnName: str + RowName: str + + def to_string(self): + return "{ReportName}/{ReportForString}/{TableName}/{ColumnName}/{RowName}".format(**asdict(self)) + +def makeResultSpec(specstr: str) -> ResultSpec: + fields = specstr.split('/') + return ResultSpec(*fields) + +def build_query(resultspec: ResultSpec, finalize = True) -> str: + if not isinstance(resultspec, ResultSpec): + resultspec = makeResultSpec(resultspec) + + agg_columns = ['ReportName'] + query = """SELECT * from TabularDataWithStrings + WHERE ReportName = :ReportName""" + + if (resultspec.ReportForString and resultspec.ReportForString != TOKEN_ANY): + query += " AND ReportForString = :ReportForString" + agg_columns.append('ReportForString') + + if (resultspec.TableName and resultspec.TableName != TOKEN_ANY): + query += " AND TableName = :TableName" + agg_columns.append('TableName') + + if (resultspec.ColumnName and resultspec.ColumnName != TOKEN_ANY): + query += " AND ColumnName = :ColumnName" + agg_columns.append('ColumnName') + + if (resultspec.RowName and resultspec.RowName != TOKEN_ANY): + query += " AND RowName = :RowName" + agg_columns.append('ReportForString') + + if finalize: + query += ";" + agg_columns.append('Units') + return query, agg_columns + +def get_a_result(sqlfile: Path, resultspec: ResultSpec, aggtype='sum') -> tuple: + + if not isinstance(resultspec, ResultSpec): + resultspec = makeResultSpec(resultspec) + + query,agg_columns = build_query(resultspec) + + if resultspec.to_string().startswith("AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/"): + # Special case. 'Total Energy' is a synthetic result not defined by EnergyPlus. + # It is not a good idea to use this because it is adding quantities with different meanings (kWh electric + kWh gas, etc). + if resultspec.RowName == TOKEN_ANY: + query,agg_columns = build_query( + "AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/*", + False) + query += """ AND ColumnName <> 'Water';""" + else: + query,agg_columns = build_query( + f"AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/{resultspec.RowName}", + False) + query += """ AND ColumnName <> 'Water';""" + + with connect(sqlfile) as conn: + try: + sim_sizing_data = pd.read_sql_query(query, conn, params=asdict(resultspec), dtype={'Value':float}) + except ValueError: + # If user requested a query that returns a string value + # To do: aggregation doesn't work with string type results. + sim_sizing_data = pd.read_sql_query(query, conn, params=asdict(resultspec)) + + if sim_sizing_data.empty: + # No data found matching result spec + return None, None + elif len(sim_sizing_data) == 1: + # Only one value, no aggregation required + return sim_sizing_data, sim_sizing_data.loc[0,'Value'] + else: + # Aggregation requested. Calculate a single float value. + sizing_agg = ( + sim_sizing_data + .groupby(agg_columns) + ['Value'].agg(aggtype).iloc[0] + ) + return sim_sizing_data, sizing_agg + +def gather_sizing_data1(subroot: Path, resultspec: ResultSpec, progressbar=False): + """ + Copy model files and hourly output files to a different folder. + + Assumes that files are placed within a "runs" subfolder. + + subroot: e.g., "C:\path\DEER-Prototypes-EnergyPlus\Analysis\SFm_Furnace_1975" + """ + + if progressbar: + from tqdm import tqdm + + if not isinstance(subroot, Path): + subroot = Path(subroot) + meas_group = subroot.name + + # Count composed models. + runs_root = subroot.joinpath('runs') + subroot_finished_list = list(runs_root.glob('**/'+FILENAME_FINISHED)) + n_models = len(subroot_finished_list) + + if progressbar: + # Create the progress bar here. + myiter = tqdm(subroot_finished_list, desc=subroot.name) + else: + myiter = subroot_finished_list + + sim_sizing_data, sizing_agg = [], [] + for sqlfile in myiter: + relpath = sqlfile.relative_to(subroot) + # E.g. relpath = CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\Msr-Res-GasFurnace-AFUE95-ECM\instance-out.sql + relstr = relpath.as_posix() # with forward slashes + # E.g. relpath = CZ01/SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace/Msr-Res-GasFurnace-AFUE95-ECM/instance-out.sql + + #_, cz, cohort, techid, _ = relpath.parts + #print(meas_group, cz, cohort, techid) + + a,b = get_a_result(sqlfile, resultspec) + a["File Name"] = relstr + + sim_sizing_data.append(a) + sizing_agg.append((relstr, b)) + + if progressbar: + myiter.close() + + sim_sizing_data = pd.concat(sim_sizing_data) + sizing_agg = pd.DataFrame(sizing_agg,columns=['File Name','Value']) + + return sim_sizing_data, sizing_agg + +def parse_query_file(queryfile: Path): + """Reads the query.txt file and returns a list of tuples (resultspec, name) + where + resultspec is a ResultSpec object + name is the name to assign to output. + + If name is ommitted in the query.txt, name will be like "ColumnName/RowName". + """ + if not isinstance(queryfile, Path): + queryfile = Path(queryfile) + + listlist_query_path_and_name = [] + list_query_path_and_name = [] + with queryfile.open() as f: + for query_line in f: + if query_line.isspace(): + if list_query_path_and_name != []: + listlist_query_path_and_name.append(list_query_path_and_name) + list_query_path_and_name = [] + continue + if query_line.startswith("#"): + continue + m = re.match(r'\s*(.+)\s*,\s*(.+)\s*',query_line) + if m: + query_path, user_column_name = m.groups() + resultspec = makeResultSpec(query_path) + else: + query_path = query_line.strip() + resultspec = makeResultSpec(query_path) + user_column_name = "{ColumnName}/{RowName}".format(**asdict(resultspec)) + list_query_path_and_name.append((resultspec, user_column_name)) + if list_query_path_and_name != []: + listlist_query_path_and_name.append(list_query_path_and_name) + return listlist_query_path_and_name + +def gather_sizing_data2(subroot: Path, queryfile: Path, progressbar=False, runspath='runs'): + r""" + Read selected data entries from SQL outputs and write to CSV. + Result set specifications are parsed from query.txt, e.g. (resultspec, name). + Output columns will have units appended to name, like "name (Units)". + + Assumes that files are placed within a "runs" subfolder under the given subroot. + + subroot: e.g., "C:\Users\User1\DEER-Prototypes-EnergyPlus\Analysis\SFm_Furnace_1975" + """ + + if progressbar: + from tqdm import tqdm + + if not isinstance(subroot, Path): + subroot = Path(subroot) + meas_group = subroot.name + + listlist_query_path_and_name = parse_query_file(queryfile) + + result_sets = [] + for list_query_path_and_name in listlist_query_path_and_name: + columns_out = ['File Name'] + [name for _,name in list_query_path_and_name] + + # Count composed models. + runs_root = subroot.joinpath(runspath) + subroot_finished_list = list(runs_root.glob('**/'+FILENAME_FINISHED)) + n_models = len(subroot_finished_list) + + if progressbar: + # Create the progress bar here. + myiter = tqdm(subroot_finished_list, desc=subroot.name) + else: + myiter = subroot_finished_list + + sim_sizing_data, sizing_agg = [], [] + for sqlfile in myiter: + relpath = sqlfile.relative_to(runs_root) + # E.g. relpath = Path(r"CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\Msr-Res-GasFurnace-AFUE95-ECM\instance-out.sql") + relstr = relpath.as_posix() # with forward slashes + # E.g. relstr = "CZ01/SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace/Msr-Res-GasFurnace-AFUE95-ECM/instance-out.sql" + #_, cz, cohort, techid, _ = relpath.parts + #print(meas_group, cz, cohort, techid) + + sizing_agg_row = {"File Name": relstr} + for resultspec, user_column_name in list_query_path_and_name: + a,b = get_a_result(sqlfile, resultspec) + if a is None: + # No data found matching the result spec. Skip this and go to next. + continue + a["File Name"] = relstr + units = a['Units'].iloc[0] + sim_sizing_data.append(a) + sizing_agg_row.update({f"{user_column_name} ({units})": b}) + sizing_agg.append(sizing_agg_row) + + if progressbar: + myiter.close() + + sim_sizing_data = pd.concat(sim_sizing_data) + sizing_agg = pd.DataFrame(sizing_agg) + result_sets.append((sim_sizing_data, sizing_agg)) + + return result_sets + +def main(): + import argparse + parser = argparse.ArgumentParser() + parser.add_argument('subroot', type=Path, default='.', + help=r'Analysis subfolder, e.g. C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975') + parser.add_argument('-q','--queryfile', type=Path, default='query.txt', + help=r'Query file, e.g. query.txt') + parser.add_argument('-d','--detailfile', type=Path, default='results-sizing-detail.csv', + help=r'Output file for detailed sizing info, e.g. results-sizing-detail.csv') + parser.add_argument('-a','--aggfile', type=Path, default='results-sizing-agg.csv', + help=r'Output file for aggregated sizing info, e.g. results-sizing-agg.csv') + parser.add_argument('-r','--runspath', type=str, default='runs', + help=r'Path within study folder to omit from "File Name" output column.') + + pargs = parser.parse_args() + result_sets = gather_sizing_data2(pargs.subroot, pargs.queryfile, True, pargs.runspath) + + output1 = BytesIO() + output2 = BytesIO() + + for sim_sizing_data, sizing_agg in result_sets: + sim_sizing_data.to_csv(output1,mode='a',index=False) + output1.write(b'\r\n') + sizing_agg.to_csv(output2,mode='a',index=False) + output2.write(b'\r\n') + + pargs.detailfile.write_bytes(output1.getbuffer()) + pargs.aggfile.write_bytes(output2.getbuffer()) + +def test1(): + specstr = "AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Site Energy" + sqlfile = r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975\runs\CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\AFUE_80_baseline\instance-out.sql" + myspec = makeResultSpec(specstr) + print(myspec) + sim_sizing_data, sizing_agg = get_a_result(sqlfile, myspec) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test2(): + specstr = "ComponentSizingSummary/Entire Facility/Coil:Heating:Fuel/Design Size Nominal Capacity/*" + sqlfile = r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975\runs\CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\AFUE_80_baseline\instance-out.sql" + myspec = makeResultSpec(specstr) + sim_sizing_data, sizing_agg = get_a_result(sqlfile, myspec) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test3(): + sim_sizing_data, sizing_agg = gather_sizing_data1( + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975", + "ComponentSizingSummary/Entire Facility/Coil:Heating:Fuel/Design Size Nominal Capacity/*", + True) + print(sim_sizing_data) + print(sizing_agg) + return sim_sizing_data, sizing_agg + +def test4(): + result_sets = gather_sizing_data2( + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975", + r"C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\DMo_Brushless_Fan_Motor_Ex\query.txt", + True) + for sim_sizing_data, sizing_agg in result_sets: + print(sim_sizing_data) + print(sizing_agg) + sim_sizing_data.to_csv('results-sim-sizing.csv',mode='a',index=False) + sizing_agg.to_csv('results-sizing-agg.csv',mode='a',index=False) + return result_sets + +def test_all(): + #sim_sizing_data, sizing_agg = test1() + #sim_sizing_data, sizing_agg = test2() + #sim_sizing_data, sizing_agg = test3() + result_set = test4() + print("Done.") + +if "__main__" == __name__: + #test_all() + main() diff --git a/commercial measures/SWHC008-04 VSD Central Plant/global.pxv b/commercial measures/SWHC008-04 VSD Central Plant/global.pxv new file mode 100644 index 00000000..c707bb60 --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/global.pxv @@ -0,0 +1,2 @@ +:timestep => 6, +:run_control => "ANNUAL" # ANNUAL | SIZING diff --git a/commercial measures/SWHC008-04 VSD Central Plant/pump_min_flow.csv b/commercial measures/SWHC008-04 VSD Central Plant/pump_min_flow.csv new file mode 100644 index 00000000..0b8f9413 --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/pump_min_flow.csv @@ -0,0 +1,289 @@ +cohort_name,climate_name,:cw_pump_min_flow_rate +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ01,97.497463 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ02,125.3651245 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ03,117.829691 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ04,126.938518 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ05,111.3738325 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ06,116.1267485 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ07,119.093142 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ08,127.8307345 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ09,129.586611 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ10,139.0193105 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ11,140.5390735 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ12,137.0927915 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ13,141.4751695 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ14,141.170799 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ15,146.1361475 +ECC&0&cPVVE&Ex&Chiller__PumpCtrl,CZ16,123.950533 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ01,75.48667 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ02,105.167321 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ03,97.5873115 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ04,106.643901 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ05,91.1460795 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ06,96.6985775 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ07,99.4455735 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ08,108.286248 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ09,109.300352 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ10,119.8627745 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ11,109.5893995 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ12,109.704322 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ13,112.970907 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ14,112.841358 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ15,117.779543 +ECC&0&cPVVE&New&Chiller__PumpCtrl,CZ16,98.085309 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ01,16.1831775 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ02,20.7814705 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ03,19.713736 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ04,21.1032535 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ05,18.560332 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ06,19.4260815 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ07,19.9066665 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ08,21.28504 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ09,21.85617 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ10,22.6425185 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ11,22.9768385 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ12,22.074871 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ13,23.029076 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ14,22.952461 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ15,23.693537 +ESe&0&cPVVE&Ex&Chiller__PumpCtrl,CZ16,20.074523 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ01,11.481106 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ02,16.514015 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ03,15.449763 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ04,16.798187 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ05,14.289394 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ06,15.4448875 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ07,15.8906475 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ08,17.250912 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ09,17.3825505 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ10,18.79157 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ11,16.208948 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ12,16.076613 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ13,16.8058485 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ14,16.844156 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ15,17.714781 +ESe&0&cPVVE&New&Chiller__PumpCtrl,CZ16,14.3318805 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ01,249.533662 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ02,295.9505115 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ03,286.2830915 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ04,298.7128305 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ05,271.78823 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ06,280.214487 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ07,285.3664975 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ08,300.731984 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ09,305.5649975 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ10,310.1521465 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ11,319.100082 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ12,311.7304155 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ13,320.7124795 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ14,320.844118 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ15,328.0605545 +EUn&0&cPVVE&Ex&Chiller__PumpCtrl,CZ16,290.9900385 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ01,177.388799 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ02,213.148502 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ03,206.5240905 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ04,215.4629715 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ05,191.8181895 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ06,201.45566 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ07,208.1970835 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ08,217.5287905 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ09,214.3625015 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ10,235.230338 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ11,230.807563 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ12,226.2740445 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ13,235.844651 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ14,236.621945 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ15,245.5364485 +EUn&0&cPVVE&New&Chiller__PumpCtrl,CZ16,207.889927 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ01,116.9904085 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ02,143.9463515 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ03,136.905433 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ04,145.8603335 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ05,132.024361 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ06,137.386018 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ07,140.789117 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ08,147.947744 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ09,151.033239 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ10,160.6804605 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ11,158.457929 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ12,154.946176 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ13,160.1079375 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ14,159.335519 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ15,164.4540975 +Hsp&0&cPVVE&Ex&Chiller__PumpCtrl,CZ16,144.3489285 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ01,99.575819 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ02,133.9933665 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ03,125.9877955 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ04,135.609943 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ05,120.5007685 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ06,126.4934545 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ07,128.7501145 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ08,137.922323 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ09,141.1826395 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ10,149.1255255 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ11,129.666012 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ12,130.274753 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ13,133.3066175 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ14,133.319851 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ15,138.037942 +Hsp&0&cPVVE&New&Chiller__PumpCtrl,CZ16,120.993194 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ01,11.9442785 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ02,15.9602975 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ03,15.026291 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ04,16.1831775 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ05,13.853385 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ06,14.6146595 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ07,14.903707 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ08,16.351034 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ09,16.3851625 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ10,17.854081 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ11,18.487896 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ12,17.8784585 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ13,18.7212235 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ14,18.519935 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ15,19.171859 +Htl&0&cPVVE&Ex&Chiller__PumpCtrl,CZ16,16.156014 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ01,10.5345625 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ02,13.754482 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ03,12.967437 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ04,13.9446265 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ05,12.0306445 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ06,12.7522185 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ07,13.40066 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ08,14.1828295 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ09,14.0769615 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ10,15.786869 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ11,15.980496 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ12,15.75483 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ13,16.4374 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ14,16.50705 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ15,17.007137 +Htl&0&cPVVE&New&Chiller__PumpCtrl,CZ16,14.077658 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ01,14.9141545 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ02,18.968481 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ03,17.9495015 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ04,19.2171315 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ05,16.872016 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ06,17.589411 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ07,17.9188555 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ08,19.2812095 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ09,19.41842 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ10,20.4694385 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ11,21.1116115 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ12,20.355909 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ13,21.179172 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ14,21.308721 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ15,21.836668 +Nrs&0&cPVVE&Ex&Chiller__PumpCtrl,CZ16,18.691274 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ01,10.662022 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ02,13.72105 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ03,13.258574 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ04,13.9501985 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ05,12.2799915 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ06,13.1171845 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ07,13.5545865 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ08,14.4976475 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ09,13.9446265 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ10,15.689359 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ11,15.453942 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ12,15.2484745 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ13,15.990247 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ14,15.970745 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ15,16.4896375 +Nrs&0&cPVVE&New&Chiller__PumpCtrl,CZ16,13.778163 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ01,96.47918 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ02,120.220079 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ03,113.6416365 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ04,121.036377 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ05,109.8429255 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ06,111.14747 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ07,111.864865 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ08,120.3517175 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ09,122.9970245 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ10,123.0889625 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ11,130.128488 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ12,125.638849 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ13,128.6247445 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ14,130.8075755 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ15,132.287638 +OfL&0&cPVVE&Ex&Chiller__PumpCtrl,CZ16,120.682555 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ01,62.8528565 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ02,78.448188 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ03,74.4077915 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ04,78.886983 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ05,70.519232 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ06,73.0370795 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ07,74.641119 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ08,79.293739 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ09,77.879844 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ10,86.5853975 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ11,86.1187425 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ12,84.7313145 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ13,87.1217025 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ14,88.632411 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ15,91.545174 +OfL&0&cPVVE&New&Chiller__PumpCtrl,CZ16,81.7238275 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ01,7.249172 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ02,9.02664 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ03,8.6707285 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ04,9.1443485 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ05,8.266062 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ06,8.4464555 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ07,8.4520275 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ08,9.107434 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ09,9.52812 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ10,8.9340055 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ11,9.8603505 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ12,9.23559 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ13,9.5845365 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ14,9.7837355 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ15,9.838759 +OfS&0&cPVVE&Ex&Chiller__PumpCtrl,CZ16,9.034998 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ01,3.762493 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ02,4.818387 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ03,4.729235 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ04,4.9054495 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ05,4.3858605 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ06,4.7410755 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ07,4.844854 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ08,5.18196 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ09,4.8734105 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ10,5.407626 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ11,5.3010615 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ12,5.0893255 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ13,5.396482 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ14,5.588716 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ15,5.7510005 +OfS&0&cPVVE&New&Chiller__PumpCtrl,CZ16,5.067734 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ01,64.0048675 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ02,85.1199615 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ03,80.5021665 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ04,87.194835 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ05,76.5808715 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ06,81.8338745 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ07,85.5030365 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ08,89.4842305 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ09,93.4793545 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ10,100.6407675 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ11,95.0520515 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ12,91.926856 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ13,96.709025 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ14,94.43147 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ15,99.528457 +Rt3&0&cPVVE&Ex&Chiller__PumpCtrl,CZ16,81.946011 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ01,45.7133845 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ02,80.5328125 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ03,74.8396215 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ04,82.3701795 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ05,70.2204335 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ06,76.0403875 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ07,77.8721825 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ08,85.1018525 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ09,90.6599225 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ10,92.3357015 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ11,65.6263195 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ12,66.521322 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ13,69.2773725 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ14,68.6268415 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ15,73.043348 +Rt3&0&cPVVE&New&Chiller__PumpCtrl,CZ16,57.9689985 diff --git a/commercial measures/SWHC008-04 VSD Central Plant/query_SWHC008.txt b/commercial measures/SWHC008-04 VSD Central Plant/query_SWHC008.txt new file mode 100644 index 00000000..3c82f422 --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/query_SWHC008.txt @@ -0,0 +1,34 @@ +ComponentSizingSummary/Entire Facility/Pump:ConstantSpeed/Design Power Consumption/CHW PUMP, CHW Pump Power (Constant) +ComponentSizingSummary/Entire Facility/Pump:ConstantSpeed/Design Power Consumption/CW PUMP, CW Pump Power (Constant) +ComponentSizingSummary/Entire Facility/Pump:VariableSpeed/Design Power Consumption/CHW PUMP, CHW Pump Power (Variable) +ComponentSizingSummary/Entire Facility/HeaderedPumps:VariableSpeed/Design Power Consumption/CW PUMP, CW Pump Power (Variable) +ComponentSizingSummary/Entire Facility/Pump:ConstantSpeed/Design Flow Rate/CW PUMP, CW Design Flow Rate (constant) (m3/s) +ComponentSizingSummary/Entire Facility/HeaderedPumps:VariableSpeed/Design Flow Rate/CW PUMP, CW Design Flow Rate (Variable)(m3/s) +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Cooling +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Interior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Exterior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Interior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Exterior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Fans +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Pumps +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Heat Rejection +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Humidification +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Heat Recovery +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Water Systems +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Refrigeration +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Generators +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Cooling +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Interior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Exterior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Interior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Exterior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Fans +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Pumps +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Heat Rejection +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Humidification +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Heat Recovery +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Water Systems +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Refrigeration +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Generators diff --git a/commercial measures/SWHC008-04 VSD Central Plant/query_power.txt b/commercial measures/SWHC008-04 VSD Central Plant/query_power.txt new file mode 100644 index 00000000..cf6aa7b4 --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/query_power.txt @@ -0,0 +1,32 @@ +ComponentSizingSummary/Entire Facility/Pump:ConstantSpeed/Design Power Consumption/CHW PUMP, CHW Pump Power (Constant) +ComponentSizingSummary/Entire Facility/Pump:ConstantSpeed/Design Power Consumption/CW PUMP, CW Pump Power (Constant) +ComponentSizingSummary/Entire Facility/Pump:VariableSpeed/Design Power Consumption/CHW PUMP, CHW Pump Power (Variable) +ComponentSizingSummary/Entire Facility/HeaderedPumps:VariableSpeed/Design Power Consumption/CW PUMP, CW Pump Power (Variable) +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Cooling +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Interior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Exterior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Interior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Exterior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Fans +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Pumps +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Heat Rejection +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Humidification +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Heat Recovery +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Water Systems +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Refrigeration +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Generators +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Heating +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Cooling +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Interior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Exterior Lighting +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Interior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Exterior Equipment +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Fans +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Pumps +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Heat Rejection +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Humidification +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Heat Recovery +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Water Systems +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Refrigeration +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Generators diff --git a/commercial measures/SWHC008-04 VSD Central Plant/rakefile.rb b/commercial measures/SWHC008-04 VSD Central Plant/rakefile.rb new file mode 100644 index 00000000..4ed80a71 --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/rakefile.rb @@ -0,0 +1,1010 @@ +# Copyright (c) 2011-2020 Big Ladder Software LLC. All rights reserved. +# See the file "license.txt" for additional terms and conditions. + +if (not defined?(Modelkit)) + begin + require("modelkit") + rescue LoadError => exception + args = ARGV.join(" ") + puts exception + puts "\e[1m\e[31mERROR: This rakefile requires the Modelkit library. Make sure that you have the\nModelkit gem installed in your local Rubygems environment, or try running the\nrakefile using your stand-alone installation of Modelkit by typing:\e[0m\n \e[1mmodelkit rake #{args}\e[0m" + exit + end +end + + +require("pathname") +require("json") + +require("modelkit/config") +require("modelkit/multitable") +require("modelkit/parametrics") +require("modelkit/parametrics/worksheet") +require("modelkit/energyplus") + + +# Add to modelkit-energyplus: +# other args: +# - which design days +# - water mains temp? +# - daylight saving time? +def generate_site_pxt(idd, ddy_path, site_path) + site_file = File.open(site_path, "w") + + if (File.exists?(ddy_path)) + input_file = OpenStudio::InputFile.open(idd, ddy_path) + else + raise("file not found: #{ddy_path.inspect}") + end + + site_locations = input_file.find_objects_by_class_name("Site:Location").to_a + + if (site_locations.empty?) + raise("could not find Site:Location object in #{ddy_path.inspect}") + else + site_file.puts(site_locations.first.to_idf) + end + + all_design_days = input_file.find_objects_by_class_name("SizingPeriod:DesignDay").to_a + selected_design_days = all_design_days.select { |dd| dd.name[/Ann Htg 99.6% Condns DB|Ann Clg 0?.4% Condns DB/i] } + + if (selected_design_days.length < 2) + puts "warning: could not find requested design days; including all design days\n" + selected_design_days = all_design_days + end + + # Write design days to site file. + selected_design_days.each { |dd| site_file.puts(dd.to_idf) } + + +# 'CorrelationFromWeatherFile' is available starting in EP 9.0. + +# Does this work for design-day only runs? +# Seems to work for annual. + site_file.puts("\n\nSite:WaterMainsTemperature,\n CorrelationFromWeatherFile;\n") + + daylight_saving_time = input_file.find_objects_by_class_name("RunPeriodControl:DaylightSavingTime").to_a + if (not daylight_saving_time.empty?) + site_file.puts + site_file.puts(daylight_saving_time.first.to_idf) + end + + site_file.close +end + + +# NOPUB Should move into Modelkit somewhere. +# Support for running simulations in parallel. +require("open3") +require("set") + +$child_pids = Set.new # Global tracking of child PIDs + +# Return PID? +def run_process(command, dir) + # NOTE: Separate processes are required to make the EnergyPlus runs thread safe! + Open3.popen3(command, :chdir => dir) do |stdin, stdout, stderr, thread| + $child_pids.add(thread.pid) + # This might work with just an instance variable or similar. + + stdin.close # All input already sent with command + + file_out = File.open("#{dir}/stdout", "w") + file_err = File.open("#{dir}/stderr", "w") + + while (line = stdout.gets) + file_out.puts(line) + #@proc_out.call(line) if (@proc_out) + end + + # This is probably not right. + while (line = stderr.gets) + file_err.puts(line) + #@proc_err.call(line) if (@proc_err) + end + + stdout.close + stderr.close + + file_out.close + file_err.close + + #print "Completed: #{File.basename(dir)}\n" + $child_pids.delete(thread.pid) + end +end + +# Search up through parent directories for one or more possible file names. +def search_parent_dirs(start_dir, *file_names) + path = nil + dir_names = start_dir.to_s.split("/") + while (not dir_names.empty?) do + file_names.each do |file_name| + test_path = "#{dir_names.join("/")}/#{file_name}" + if (File.exist?(test_path)) + path = test_path + break + end + end + break if (path) + dir_names.pop + end + return(path) +end + +# Search for a file name or partial path in an array of provided directories. +# Directories are expected to already be absolute paths. +def resolve_path(path, dirs) + resolved_path = nil + dirs.each do |dir| + expanded_path = File.expand_path(path, dir) + if (File.exist?(expanded_path)) + resolved_path = expanded_path + break + end + end + return(resolved_path) +end + +# Clean up any previous output files left behind if 'compose' or 'run' fails. +# Leftover files can be processed unintentionally by downstream tasks and +# ultimately generate false results. +def clean_energyplus_output_files(dir) + # Not all of these files might be present. Others might be present and unhandled. + paths = [ + "#{dir}/instance-out.err", + "#{dir}/instance-out.rdd", + "#{dir}/instance-out.sql", # Most important for downstream tasks + "#{dir}/instance-tbl.htm", + "#{dir}/instance-var.csv", + "#{dir}/stderr", + "#{dir}/stdout" + ] + FileUtils.rm_f(paths) +end + + +# Rake stubbornly sets the working directory to wherever the Rakefile is located. +# The target directory could optionally be set from a CLI option instead. +study_dir = Rake.application.original_dir + +climates_csv_path = "#{study_dir}/climates.csv" +cohorts_csv_path = "#{study_dir}/cohorts.csv" + +query_path = "#{study_dir}/query.txt" +results_summary_path = "#{study_dir}/results-summary.csv" +results_profile_elec_path = "#{study_dir}/results-profile-elec.csv" +results_profile_gas_path = "#{study_dir}/results-profile-gas.csv" +results_paths = [results_summary_path, results_profile_elec_path, results_profile_gas_path] + +cases_dir = "#{study_dir}/cases" +runs_dir = "#{study_dir}/runs" +runs_pathname = Pathname.new(runs_dir) + +MUTEX = Mutex.new # Thread lock for when something needs to run in a single thread + +config_path = search_parent_dirs(study_dir, ".modelkit-config") +if (not config_path) + raise("modelkit-config file not found in working directory or any parent directory") +else + CONFIG = Modelkit::Config.new(config_path) + puts "Using modelkit-config at #{config_path}\n" +end + +config = Hash.new +[:prototypes_dir, :templates_dir, :weather_dir, :codes_dir].each do |key| + config[key] = [] + field = key.to_s.gsub(/_/, "-") + if (not CONFIG[field]) + raise("#{field} variable missing in modelkit-config") + else + config_paths = CONFIG[field].split(/\s*;\s*/) # Split string with semicolons into array of paths + config_paths.each do |path| + # Resolve path relative to modelkit-config file and normalize the slashes. + config[key] << File.expand_path(path.strip.gsub(/\\/, "/"), File.dirname(config_path)) + end + end +end + +max_workers = CONFIG["max-workers"] +if (max_workers.nil?) + max_workers = 1 +end + +global_pxv_path = search_parent_dirs(study_dir, "global.pxv") +if (global_pxv_path) + puts "Using global.pxv at #{global_pxv_path}\n" +end + +rake_tasks = Rake.application.top_level_tasks +rake_task_name = rake_tasks.first # Multiple tasks are allowed, but assume one + +rake_options = Rake.application.options +rake_options.always_multitask = true # --multitask, -m +#rake_options.job_stats = true # --job-stats true | :history +rake_options.thread_pool_size = max_workers - 1 # --jobs, -j (default 12 on Mac) + +if (rake_options.dryrun or rake_options.show_all_tasks or + rake_options.show_prereqs or rake_options.show_tasks) + # These are information-only requests. Rake nonetheless registers as invoked + # with the "default" task name but nothing actually gets run. + rake_task_name = "none" +end + + +# Show threads message and info about how to change +# Running with 8 threads (edit .modelkit-config to change). +# Type Ctrl+C to cancel all tasks. + +require "io/console" # need this anyway for progress bar + +#$stdin.echo = false # turn off echo; in Mac shows a cursor with a key icon +# This prevents the user from over-typing the output stream. + +# also try switching to raw mode--should also block user input; maybe no key icon? + +#print "\e[?25l" # hide the cursor; MUST remember to show it again on exit or else it's permanent for the session! + + +trap("INT") do # Ctrl+C (polite kill) + puts "Canceling all tasks.\n" + if ($child_pids) + $child_pids.each { |pid| Process.kill("KILL", pid) } + end + exit +end + +if (Modelkit::Platform.unix?) + trap("TSTP") do # Ctrl+Z (suspend) + puts "Suspending all tasks. Type 'fg' to resume.\n" + exit + end +end + +if (not rake_task_name =~ /^(prune|clean|none)$/) + +# If possible, detect if any tasks will be run before showing this message: +puts "\e[1mType Ctrl+C to cancel all tasks.\e[0m\n" + +end + +# modelkit rake -A crashes for some reason + +# NOPUB Some of above could be included here too. +# Don't evaluate worksheets and generate file tasks if not necessary! +# NOTE: prune does need to evaluate worksheets. +if (not rake_task_name =~ /^(clean|none)$/) + + pxv_paths = [] + site_paths = [] + + compose_idf_paths = [] + + + #rename size_ to sizerun_ size_run_ sizing_run_ + size_ref_paths = [] + size_idf_paths = [] + size_sql_paths = [] + size_json_paths = [] + + hardsize_idf_paths = [] + + run_sql_paths = [] + run_csv_paths = [] + + + + old_site_paths = Dir.glob("#{runs_dir}/*/site.pxt") + old_pxv_paths = Dir.glob("#{runs_dir}/**/instance.pxv") + + climates = Modelkit::Worksheet.open(climates_csv_path) + cohorts = Modelkit::Worksheet.open(cohorts_csv_path) + + climate_pattern = ENV["CLIMATE"] || "" + + new_case_csv = "skip,case_name\n,defaults\n" # Could be read from config instead + + cohorts_first_pass = true + + puts "Evaluating worksheets...\n" + + csv_table = climates.each_row do |row1, index1, variables1, parameters1| + #puts "climate_index = #{index1}" + + if (not variables1.key?(:climate)) + raise("required column \"climate\" is missing in #{File.basename(climates_csv_path)}") + end + + climate_name = variables1[:climate].to_s.strip # Could have been converted to non-string by Util.value_from_string + if (climate_name.empty?) + raise("climate field cannot be blank for row #{index1 + 2} of #{File.basename(climates_csv_path)}") + end + + next if (not climate_name =~ Regexp.new(climate_pattern)) + + FileUtils.mkdir_p("#{runs_dir}/#{climate_name}") + + site_path = "#{runs_dir}/#{climate_name}/site.pxt" + if (site_paths.include?(site_path)) + puts "warning: duplicate name #{climate_name.inspect} in climate column at row #{index1 + 2} in #{File.basename(climates_csv_path)}; row will be skipped" + next + end + + site_paths << site_path + + if (not variables1.key?(:weather_file)) + raise("required column \"weather_file\" is missing in #{File.basename(climates_csv_path)}") + end + + weather_name = variables1[:weather_file].to_s.strip # Could have been converted to non-string by Util.value_from_string + if (weather_name.empty?) + raise("weather_file field cannot be blank for row #{index1 + 2} of #{File.basename(climates_csv_path)}") + end + + epw_path = resolve_path(weather_name, config[:weather_dir]) + if (not epw_path) + puts "Could not resolve path #{weather_name.inspect} from possible paths:\n" + config[:weather_dir].each { |dir| puts " #{File.expand_path(weather_name, dir).inspect}\n" } + puts "Check the weather-dir variable in modelkit-config file.\n" + raise("weather file #{weather_name.inspect} not found for row #{index1 + 2} of #{File.basename(climates_csv_path)}") + end + + if (not File.file?(epw_path)) + raise("weather file #{epw_path.inspect} is not a file for row #{index1 + 2} of #{File.basename(climates_csv_path)}") + end + + ddy_path = "#{File.dirname(epw_path)}/#{File.basename(epw_path, ".*")}.ddy" # Ensure ddy is from same directory as resolved epw file + if (not File.exist?(ddy_path)) + puts "Weather file path resolved to #{epw_path.inspect}\n" + raise("ddy file #{ddy_path.inspect} not found for row #{index1 + 2} of #{File.basename(climates_csv_path)}") + end + + # This file only exists to indicate if the weather file changes for dependency purposes. + # The weather file is the one input that is separate from instance parameters. + weather_path = "#{runs_dir}/#{climate_name}/weather" + pathname = Pathname.new(weather_path).relative_path_from(runs_pathname) + + if (File.exist?(weather_path)) + old_epw_path = File.read(weather_path) + if (epw_path != old_epw_path) + puts "Updating: #{pathname}\n" + File.write(weather_path, epw_path) + end + else + puts "Writing: #{pathname}\n" + File.write(weather_path, epw_path) + end + + # generate site.pxt from .ddy file + file site_path => [weather_path, ddy_path] do + idd = open_data_dictionary + pathname = Pathname.new(site_path).relative_path_from(runs_pathname) + puts "Generating: #{pathname}\n" + generate_site_pxt(idd, ddy_path, site_path) + end + + if (variables1.key?(:codes_file)) # NOTE: codes_file is an optional column + codes_name = variables1[:codes_file].to_s.strip # Could have been converted to non-string by Util.value_from_string + if (codes_name.empty?) + raise("codes_file field cannot be blank for row #{index1 + 2} of #{File.basename(climates_csv_path)}") + end + + codes_path = resolve_path(codes_name, config[:codes_dir]) + if (not codes_path) + puts "Could not resolve path #{codes_name.inspect} from possible paths:\n" + config[:codes_dir].each { |dir| puts " #{File.expand_path(codes_name, dir).inspect}\n" } + puts "Check the codes-dir variable in modelkit-config file.\n" + raise("codes file #{codes_name.inspect} not found for row #{index1 + 2} of #{File.basename(climates_csv_path)}") + end + + if (not File.file?(codes_path)) + raise("codes file #{codes_path.inspect} is not a file for row #{index1 + 2} of #{File.basename(climates_csv_path)}") + end + + codes_table = Modelkit::MultiTable.new(codes_path) + + else + codes_table = nil # Must set something to pass to next worksheet + end + + variables1[:codes] = codes_table # For backwards compatibility + + # Make sure objects passed in are not mutated by the Worksheet. Make dupes? + + cohort_names = [] # Accumulate names to check for duplicates + + cohorts.each_row(variables1) do |_, index2, variables2, parameters2| + #puts " cohort_index = #{index2}" + + # NOTE: Variables from outer worksheet (variables1) are copied into this worksheet. + # Changes to the variables here (variables2) do not propagate back up. + + if (not variables2.key?(:cohort)) + raise("required column \"cohort\" is missing in #{File.basename(cohorts_csv_path)}") + end + + cohort_name = variables2[:cohort].to_s.strip # Could have been converted to non-string by Util.value_from_string + if (cohort_name.empty?) + raise("cohort field cannot be blank for row #{index2 + 2} of #{File.basename(cohorts_csv_path)}") + end + + if (cohort_names.include?(cohort_name)) + if (cohorts_first_pass) # Only warn about this row once + puts "warning: duplicate name #{cohort_name.inspect} in cohort column at row #{index2 + 2} in #{File.basename(cohorts_csv_path)}; row will be skipped" + end + next + end + + cohort_names << cohort_name + + cases_csv_path = "#{cases_dir}/#{cohort_name}.csv" + cases_csv_short_path = "#{File.basename(cases_dir)}/#{cohort_name}.csv" + if (not File.exist?(cases_csv_path)) + puts("Cases worksheet #{cases_csv_short_path.inspect} not found for row #{index2 + 2} of #{File.basename(cohorts_csv_path)}\n") + puts("Creating: #{cases_csv_short_path}\n") + FileUtils.mkdir_p(cases_dir) + File.write(cases_csv_path, new_case_csv) + end + + if (not variables2.key?(:root)) + raise("required column \"root\" is missing in #{File.basename(cohorts_csv_path)}") + end + + root_name = variables2[:root].to_s.strip # Could have been converted to non-string by Util.value_from_string + if (root_name.empty?) + raise("root field cannot be blank for row #{index2 + 2} of #{File.basename(cohorts_csv_path)}") + end + + root_path = resolve_path(root_name, config[:prototypes_dir]) + if (not root_path) + puts "Could not resolve path #{root_name.inspect} from possible paths:\n" + config[:prototypes_dir].each { |dir| puts " #{File.expand_path(root_name, dir).inspect}\n" } + puts "Check the prototypes-dir variable in modelkit-config file.\n" + raise("root template #{root_name.inspect} not found for row #{index2 + 2} of #{File.basename(cohorts_csv_path)}") + end + + if (not File.file?(root_path)) + raise("root template #{root_path.inspect} is not a file for row #{index2 + 2} of #{File.basename(cohorts_csv_path)}") + end + + case_names = [] # Accumulate names to check for duplicates + + # Better to pre-read and cache this outside the looping? + # There are only N worksheets...1 per building type. + cases = Modelkit::Worksheet.open(cases_csv_path) + + cases.each_row(variables2) do |_, index3, variables3, parameters3| + #puts " case_index = #{index3}" + + # NOTE: Variables from outer worksheet (variables2) are copied into this worksheet. + # Changes to the variables here (variables3) do not propagate back up. + + if (not variables3.key?(:case_name)) + raise("required column \"case_name\" is missing in #{File.basename(cases_dir)}/#{File.basename(cases_csv_path)}") + end + + case_name = variables3[:case_name].to_s.strip # Could have been converted to non-string by Util.value_from_string + if (case_name.empty?) + raise("case_name field cannot be blank for row #{index3 + 2} of #{File.basename(cases_dir)}/#{File.basename(cases_csv_path)}") + end + + if (case_names.include?(case_name)) + if (cohorts_first_pass) # Only warn about this row once + puts "warning: duplicate name #{case_name.inspect} in case_name column at row #{index3 + 2} in #{File.basename(cases_dir)}/#{File.basename(cases_csv_path)}; row will be skipped" + end + next + end + + case_names << case_name + run_name = "#{climate_name}/#{cohort_name}/#{case_name}" + case_dir = "#{runs_dir}/#{run_name}" + FileUtils.mkdir_p(case_dir) + + # better to create this dynamically in cases.csv by combining variables from other layers. + # all variables need to be propagated first from layer to layer. + # for example: + # :run_name + # %= "My Prefix Something: #{climate}/#{cohort}/#{case_name}" + pxv_string = ":run_name => #{run_name.inspect},\n" + + parameters = parameters1 | parameters2 | parameters3 + parameters.each do |key, value| + value_inspect = value.inspect + if (value.kind_of?(String)) + # Using `inspect` on strings is useful because it reveals invisible + # characters and invalid byte sequences. The downside is that the + # string must be unescaped. + value_inspect.gsub!(/\\\\/, "\\") + end + pxv_string << ":#{key} => #{value_inspect},\n" + end + + pxv_path = "#{case_dir}/instance.pxv" + pxv_paths << pxv_path + + pathname = Pathname.new(pxv_path).relative_path_from(runs_pathname) + + if (File.exist?(pxv_path)) + old_pxv_string = File.read(pxv_path) + if (pxv_string != old_pxv_string) + puts "Updating: #{pathname}\n" + File.write(pxv_path, pxv_string) + end + else + puts "Writing: #{pathname}\n" + File.write(pxv_path, pxv_string) + end + + compose_idf_path = "#{case_dir}/instance.idf" + compose_idf_paths << compose_idf_path + + if (variables3[:sizing_case]) + size_name = "#{climate_name}/#{cohort_name}/#{variables3[:sizing_case]}" + size_dir = "#{runs_dir}/#{size_name}" + size_ref_path = "#{size_dir}/instance.idf" + + size_idf_path = "#{size_dir}/instance-size.idf" + size_sql_path = "#{size_dir}/instance-size-out.sql" + size_json_path = "#{size_dir}/instance-size-out.json" + + if (size_ref_paths.include?(size_ref_path)) + # Avoid creating redundant tasks when multiple cases reference same sizing case. + create_sizing_tasks = false + else + create_sizing_tasks = true + + size_ref_paths << size_ref_path + size_idf_paths << size_idf_path + size_sql_paths << size_sql_path + size_json_paths << size_json_path + end + + hardsize_idf_path = "#{case_dir}/instance-hardsize.idf" + hardsize_idf_paths << hardsize_idf_path + + run_idf_path = hardsize_idf_path # Which input file to run + + run_sql_path = "#{case_dir}/instance-hardsize-out.sql" + run_sql_paths << run_sql_path + + run_csv_path = "#{case_dir}/instance-hardsize-var.csv" + run_csv_paths << run_csv_path + + else + # Autosize-only run. + size_ref_path = nil + + run_idf_path = compose_idf_path # Which input file to run + + run_sql_path = "#{case_dir}/instance-out.sql" + run_sql_paths << run_sql_path + + run_csv_path = "#{case_dir}/instance-var.csv" + run_csv_paths << run_csv_path + end + + # Compose input file from parameter file. + # need more dependencies here: template files + file compose_idf_path => [site_path, root_path, pxv_path, global_pxv_path].compact do # If no path for global.pxv, remove nil element + pathname = Pathname.new(compose_idf_path).relative_path_from(runs_pathname) + puts "Composing: #{pathname}\n" + + clean_energyplus_output_files(File.dirname(compose_idf_path)) + + site_dir = File.dirname(site_path) + + begin + Modelkit::Parametrics.template_compose(root_path, + :annotate => CONFIG["template-compose.annotate"], + :indent => CONFIG["template-compose.indent"], + :esc_line => CONFIG["template-compose.esc-line"], + :dirs => [site_dir, *config[:templates_dir]], + :files => [global_pxv_path, pxv_path].compact, # If no path for global.pxv, remove nil element + :output => compose_idf_path) + rescue Exception => exception + puts "#{exception.class.name}: #{exception.message}\n" + puts "#{exception.backtrace.first}\n" if (not SyntaxError === exception) + puts "Skipping: #{pathname}\n" + end + end + + if (create_sizing_tasks) + # Generate a modified input file in order to run a design-day-only simulation. + # NOTE: This can be eliminated if a design-day option is added to energyplus-run. + file size_idf_path => size_ref_path do + pathname = Pathname.new(size_idf_path).relative_path_from(runs_pathname) + puts "Generating size run: #{pathname}\n" + + FileUtils.cp(size_ref_path, size_idf_path) + + idd = open_data_dictionary + input_file = OpenStudio::InputFile.open(idd, size_idf_path) + + sc_objs = input_file.find_objects_by_class_name("SimulationControl") + if sc_objs.length != 1 + raise "More than one SimulationControl object found" + end + sc = sc_objs[0] + sc.fields[1] = "Yes" + sc.fields[2] = "Yes" + sc.fields[3] = "Yes" + sc.fields[4] = "Yes" + sc.fields[5] = "No" + + input_file.write(size_idf_path) + end + + # Run sizing input files for design days only. + file size_sql_path => size_idf_path do + pathname = Pathname.new(size_idf_path).relative_path_from(runs_pathname) + puts "Running size run: #{pathname}\n" + + command = "modelkit-energyplus energyplus-run --weather=\"#{epw_path}\" \"#{size_idf_path}\"" + run_process(command, size_dir) + end + + # Generate size data file (instance-size-out.json). + file size_json_path => size_sql_path do + pathname = Pathname.new(size_json_path).relative_path_from(runs_pathname) + puts "Extracting size data: #{pathname}\n" + + # Make a copy to work on because the original gets overwritten by EnergyPlus.size. + temp_path = "#{File.dirname(size_idf_path)}/instance-temp.idf" + FileUtils.cp(size_idf_path, temp_path) + + idd = open_data_dictionary + input_file = OpenStudio::InputFile.open(idd, temp_path) + sql = Modelkit::EnergyPlus::SQLOutput.new(size_sql_path) + + # This will be fixed to only generate JSON and not modify the input file. + _, count, output_file = Modelkit::EnergyPlus.size( + sql, input_file, {json: size_json_path, version: "9-2"}) + #puts("#{count} modifications made") + + FileUtils.rm_f(temp_path) + end + end + + if (hardsize_idf_path) + # This would be a reasonable place to use `multitask` because compose_idf_path and + # size_json_path are independent and can be run concurrently. However, it seems + # like `multitask` doesn't compare timestamps like `file` does. Instead it + # always runs like a regular `task`. + file hardsize_idf_path => [compose_idf_path, size_json_path] do + pathname = Pathname.new(hardsize_idf_path).relative_path_from(runs_pathname) + puts "Applying hard sizes: #{pathname}\n" + + idd = open_data_dictionary + input_file = OpenStudio::InputFile.open(idd, compose_idf_path) + + json_string = File.read(size_json_path) + value_map = JSON.parse(json_string, {:symbolize_names=>true}) + output_file, count = Modelkit::EnergyPlus.modify_objects(input_file, value_map) + #puts("#{count} modifications made") + + # Set SimulationControl fields 1, 2, and 3 to "No", "No", and "No" + sc_objs = output_file.find_objects_by_class_name("SimulationControl") + if sc_objs.length != 1 + raise "More than one SimulationControl object found" + end + sc = sc_objs[0] + sc.fields[1] = "No" + sc.fields[2] = "No" + sc.fields[3] = "No" + # Remove Sizing:Zone and Sizing:System objects + sizing_zones = output_file.find_objects_by_class_name("Sizing:Zone") + sizing_systems = output_file.find_objects_by_class_name("Sizing:System") + sizing_plants = output_file.find_objects_by_class_name("Sizing:Plant") + (sizing_zones + sizing_systems + sizing_plants).each {|x| output_file.delete_object(x)} + + output_file.write(hardsize_idf_path) + end + end + + # Run input file in a separate process. + file run_sql_path => [epw_path, run_idf_path] do + # Not sure why this check is needed; seems to try to run if even IDF does not exist. + # May need in other places, like sizing run. + next if (not File.exist?(run_idf_path)) + + pathname = Pathname.new(run_idf_path).relative_path_from(runs_pathname) + puts "Running: #{pathname}\n" + + # Because this is spawned to the shell, .modelkit-config options will be + # automatically applied. + # NOTE: If modelkit-energyplus was thread safe, would not have to run this + # as a separate process. + command = "modelkit-energyplus energyplus-run --weather=\"#{epw_path}\" \"#{run_idf_path}\"" + run_process(command, case_dir) + #$bar.inc + end + + + # see discussion with Michael + file run_csv_path => run_sql_path + + # deleting instance-out.csv breaks it; doesn't know how to recover + + end + end + + cohorts_first_pass = false + end + + + prune_paths = (old_site_paths - site_paths) + (old_pxv_paths - pxv_paths) + + if (not prune_paths.empty? and not rake_task_name =~ /^(prune|clean|none)$/) + puts "\e[1m\e[33mNote: There are cases in the runs directory that are not referenced by any\n" \ + "worksheet. You may want to delete them by typing:\e[0m\n \e[1mmodelkit rake prune\e[0m\n" + end + +end + + +desc "Generate case files" +task :cases do + # No operation; cases are generated when worksheets are evaluated. +end + + +desc "Delete unreferenced files" +task :prune do + if (prune_paths.empty?) + puts "Prune has nothing to delete." + else + prune_dirs = [] + puts "\e[1m\e[31mPrune will delete the following files:\e[0m" + +# show each as: dirname/* (106 files) + + prune_paths.each do |path| + dir = File.dirname(path) + prune_dirs << dir + pathname = Pathname.new(dir).relative_path_from(runs_pathname) + puts " \e[31m#{pathname}\e[0m" + end + print "\e[1m\e[31mConfirm (y/n)?\e[0m " + + input = ENV["CONFIRM"] || $stdin.gets || "" + if (ENV["CONFIRM"] or not $stdin.tty?) + puts input # Echo when not already written to STDOUT + end + + $start_time = Time.now # Reset to cut out wait time on the user prompt + if (input.strip =~ /^y/i) + puts "Pruning files..." + + # maybe don't have to repeat this--already said what was to be deleted + prune_dirs.each do |dir| + pathname = Pathname.new(dir).relative_path_from(runs_pathname) + puts "Deleting: #{pathname}" + FileUtils.rm_rf(dir) + end + else + puts "Task canceled." + end + end +end + + +desc "Delete all files and results" +task :clean do + paths = []; names = [] + [runs_dir, *results_paths].each do |path| + if (File.directory?(path)) + count = Dir.glob("#{path}/**/*").count { |f| File.file?(f) } + if (count.nonzero?) + paths << Dir.glob("#{path}/*") + names << "#{File.basename(path)}/* (#{count} files)" + end + elsif (File.file?(path)) + paths << path + names << File.basename(path) + end + end + + if (paths.empty?) + puts "Clean has nothing to delete." + else + puts "\e[1m\e[31mClean will delete the following files:\e[0m" + names.each { |name| puts " \e[31m#{name}\e[0m"} + print "\e[1m\e[31mConfirm (y/n)?\e[0m " + + input = ENV["CONFIRM"] || $stdin.gets || "" + if (ENV["CONFIRM"] or not $stdin.tty?) + puts input # Echo when not already written to STDOUT + end + + $start_time = Time.now # Reset to cut out wait time on the user prompt + if (input.strip =~ /^y/i) + puts "Cleaning files..." + FileUtils.rm_rf(paths) + else + puts "Task canceled." + end + end +end + + +desc "Generate site files (site.pxt)" +multitask :sites => site_paths + + +desc "Compose input files" +multitask :compose => compose_idf_paths + + +# Generate size input files +multitask :"size-idf" => size_idf_paths + + +# Run size input files +multitask :"size-sql" => size_sql_paths + + +# Extract size data +multitask :"size-json" => size_json_paths + + +desc "Apply hard sizes to input files" +multitask :hardsize => hardsize_idf_paths + + +desc "Run input files" +multitask :run => run_sql_paths + + +file query_path do + puts "Query file not found.\n" + query = +"AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Energy Per Total Building Area/Net Site Energy, Net Site EUI +AnnualBuildingUtilityPerformanceSummary/Entire Facility/Site and Source Energy/Total Energy/Net Site Energy, Net Site Energy +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Electricity/Total End Uses, Electricity +AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Natural Gas/Total End Uses, Natural Gas\n" + File.write(query_path, query) + puts "Writing default query file: #{query_path}\n" +end + + +file results_summary_path => [*run_sql_paths, query_path] do + pathname = Pathname.new(results_summary_path).relative_path_from(Pathname.new(study_dir)) + puts "Processing: #{pathname}\n" + + short_paths = run_sql_paths.map { |path| Pathname.new(path).relative_path_from(runs_pathname) } + Modelkit::EnergyPlus.sql(short_paths, query_path, :dir => runs_dir, :output => results_summary_path) +end + + +file results_profile_elec_path => run_csv_paths do + aggregate_profiles("Electricity:Facility", results_profile_elec_path, run_csv_paths, runs_pathname, study_dir) +end + + +file results_profile_gas_path => run_csv_paths do + aggregate_profiles("Gas:Facility", results_profile_gas_path, run_csv_paths, runs_pathname, study_dir) +end + + +desc "Aggregate the simulation results" +task :results => results_paths + + +task :default => :results + + +def aggregate_profiles(column_name, output_path, run_csv_paths, runs_pathname, study_dir) + pathname = Pathname.new(output_path).relative_path_from(Pathname.new(study_dir)) + puts "Processing: #{pathname}\n" + + short_paths = run_csv_paths.map { |path| Pathname.new(path).relative_path_from(runs_pathname) } + + columns = [] + column_header = nil + date_time = true + short_paths.each do |short_path| + csv_path = "#{runs_pathname}/#{short_path}" + if (File.exist?(csv_path)) + csv = CSV.read(csv_path, :headers=>true) + if (date_time) + column = csv["Date/Time"] + column.unshift("Date/Time") # Add header + columns << column + date_time = false + end + if (not column_header) + # Match column name to the header while ignoring units/interval, i.e., [J](Hourly). + column_header = csv.headers.find { |header| header.match(column_name) } + end + column = csv[column_header] + column.unshift(short_path) # Add header + columns << column + else + puts "warning: file not found: #{csv_path}\n" + end + end + + File.open(output_path, "w") do |file| + columns.transpose.each { |row| file.puts(row.join(",")) } + end +end + + +# NOPUB consider building this into modelkit-energyplus. +# basically caches IDD path and avoids concurrent openings. + +# Open the EnergyPlus IDD if needed, but only do it once. +def open_data_dictionary + MUTEX.synchronize do # Lock to prevent opening multiple times concurrently + if (@idd.nil?) + puts "Opening Energy+.idd...\n" + + if (path = CONFIG["energyplus-run.engine"]) + path = File.expand_path(path.gsub(/\\/, "/")) # Resolve path and normalize + if (File.exist?(path)) + idd_path = "#{path}/Energy+.idd" + if (not File.exist?(idd_path)) + raise("Energy+.idd not found in specified EnergyPlus directory: #{path}") + end + else + raise("EnergyPlus directory not found: #{path}") + end + else + raise("energyplus-run.engine field missing in .modelkit-config") + end + + @idd = OpenStudio::DataDictionary.open(idd_path) + end + end + return(@idd) +end + + +# NICE, works +#require "rake/cpu_counter" +#puts "cpu=#{Rake::CpuCounter.count}" + +# Almost works but not quite: + +# shows what command was invoked from CLI +# if blank (even with -T), it's "default". +#puts "top level:" +# cli_tasks = Rake.application.top_level_tasks +# cli_task_name = cli_tasks.first # could be more than one; just grab first for now +# puts "cli_task_name=#{cli_task_name}" # returns String + +# cli_task = Rake.application.tasks.find { |t| t.name == cli_task_name } # returns Rake::Task +# puts "cli_task=#{cli_task}" +# + +# +## Rake has this builtin: +# Rake.application.lookup(task_name) => task + +# work_to_do = false +# if (cli_task.needed?) +# # Just because needed doesn't mean there is any work to do--check prereqs! +# cli_task.prerequisite_tasks.each do |prereq| +# if (prereq.needed?) +# work_to_do = true +# break +# end +# end +# end +# +# if (work_to_do) +# puts "Work to do!" +# else +# puts "Up to date; nothing to do." +# end + + +$start_time = Time.now +#$bar = RakeProgressbar.new(run_sql_paths.length) + +at_exit do + #$bar.finished + if (not rake_task_name =~ /^none$/) + puts "Elapsed task duration: #{Time.now - $start_time} sec" + end +end diff --git a/commercial measures/SWHC008-04 VSD Central Plant/result2.py b/commercial measures/SWHC008-04 VSD Central Plant/result2.py new file mode 100644 index 00000000..80562acf --- /dev/null +++ b/commercial measures/SWHC008-04 VSD Central Plant/result2.py @@ -0,0 +1,672 @@ +#!/usr/bin/env python +# coding: utf-8 + +"""EnergyPlus batch results data scraping tool, including DEER peak period. + +Features: +* Read from instance-out.sql files using result spec format like modelkit +* Apply DEER peak period calculation to hourly results and include those. +* Requires python >= 3.7.1 and additional package "tqdm" + +Usage: + Prerequisite: running models, select a query file, path to DEER peak period definitions + $terminal1> cd C:/DEER-Prototypes-EnergyPlus/ + $terminal1> python "scripts/result2.py" "commercial measures/SWXX000-00 Measure Name" --queryfile "querylibrary/query_default.txt" + +Changelog + * 2024-05-01 Adapted result.py for DEER Peak period calculation + * 2024-05-15 Filename patterns updated to match folders like runs1, runs-Asm, etc. + +@Author: Nicholas Fette +@Date: 2024-05-01 + +""" + +# Select columns from hourly files to apply DEER peak calculation +DEERPEAK_COLUMNS = ["Electricity:Facility [J](Hourly)"] +# Do you want to append "(units)"" in the column name, if available? +APPEND_UNITS = False + +##STEP 0: Setup (import all necessary libraries) +import re +from dataclasses import dataclass, asdict +from sqlite3 import connect, Connection +from pathlib import Path +from functools import cache +import argparse +import concurrent.futures +try: + # itertools.batched available only after python 3.12 + from itertools import batched +except: + from itertools import islice + def batched(iterable, n): + # batched('ABCDEFG', 3) → ABC DEF G + if n < 1: + raise ValueError('n must be at least one') + it = iter(iterable) + while batch := tuple(islice(it, n)): + yield batch + +# Third-party packages +import numpy as np +import pandas as pd +import tqdm + +def get_deer_peak_day(bldgloc: str): + """Return a for DEER peak period start day lookups. + + Input: + BldgLoc: str + CEC climate zone, e.g. CZ01 through CZ16. + + Returns: + PkDay: int + 1-based day number index for first day of the 3-day DEER peak period. + """ + peakperspec = dict([ + ("CZ01",238), + ("CZ02",238), + ("CZ03",238), + ("CZ04",238), + ("CZ05",259), + ("CZ06",245), + ("CZ07",245), + ("CZ08",245), + ("CZ09",244), + ("CZ10",180), + ("CZ11",180), + ("CZ12",180), + ("CZ13",180), + ("CZ14",180), + ("CZ15",180), + ("CZ16",224), + ]) + return peakperspec[bldgloc] + +@cache +def get_deer_peak_multipliers(BldgLoc: str, + days=3, start_hr=16, end_hr=21, dst=True): + """Return a masking array useful to calculate an average over DEER Peak Period. + + Note that for compatibility, simulation data must be an 8760-length array + that represents one annual period (no gaps or duplicates due to dst). + + Inputs: + BldgLoc: str + CEC climate zone, e.g. CZ01 through CZ16. + days: int + The number of days in the DEER Peak Period (default 3) + start_hr: int + The time of day (hour) at which DEER Peak starts, in prevailing time. + For example, start_hr=16 means the DEER Peak starts at 4 PM. + end_hr: int + The time of day (hour) at which DEER Peak ends, in prevailing time. + For example, start_hr=21 means the DEER Peak ends at 9 PM. + dst: bool + Clarifies the interpretation of start_hr. + If dst = False, then no adjustment is made for start_hr. + If dst = True, then assume Daylight Saving Time is active + during the DEER Peak, and make the appropriate offset. + + Usage: + load_data = get_load_8760('CZ11', ...) # replace with your load data as a np.ndarray + dpm = deer_peak_multipliers('CZ11') + dpload = sum(load_data * dpm) + """ + peak_day = get_deer_peak_day(BldgLoc) + # In case start_hr and end_hr are given in daylight saving time (DST), shift back to standard time. + # time_dst = time_standard + 1 + start_hr -= 1 * dst + end_hr -= 1 * dst + # Fill an array with 0-based hour of year. + hour_of_year = np.arange(0,8760) + # Calculate 0-based hour and day (standard time; this is never DST). + hour_of_day_0 = np.mod(hour_of_year, 24) + day_of_year_0 = np.mod(hour_of_year//24, 365) + # Calculate 1-based hour and day (matches conventions of DEER post-process script). + hour_of_day_1 = hour_of_day_0 + 1 + day_of_year_1 = day_of_year_0 + 1 + # Is the hour in the DEER Peak period? + is_deer_peak_day = (day_of_year_1 >= peak_day) * (day_of_year_1 <= peak_day + days) + is_deer_peak_hour = (hour_of_day_0 >= start_hr) * (hour_of_day_0 < end_hr) + is_deer_peak = is_deer_peak_day * is_deer_peak_hour + # Normalize + multipliers8760 = is_deer_peak / sum(is_deer_peak) + return multipliers8760 + +@dataclass +class ResultSpec(object): + ReportName: str + ReportForString: str + TableName: str + ColumnName: str + RowName: str + + def to_string(self): + return "{ReportName}/{ReportForString}/{TableName}/{ColumnName}/{RowName}".format(**asdict(self)) + +def makeResultSpec(specstr: str) -> ResultSpec: + fields = specstr.split('/') + return ResultSpec(*fields) + +@cache +def parse_query_file(queryfile: Path): + """Reads the query.txt file and returns a list of tuples (resultspec, name) + where + resultspec is a ResultSpec object + name is the name to assign to output. + + If name is ommitted in the query.txt, name will be like "ColumnName/RowName". + """ + if not isinstance(queryfile, Path): + queryfile = Path(queryfile) + + listlist_query_path_and_name = [] + list_query_path_and_name = [] + lines = queryfile.read_text().split('\n') + for query_line in lines: + # Blank line indicates a new group + if len(query_line.strip()) == 0: + if list_query_path_and_name != []: + listlist_query_path_and_name.append(list_query_path_and_name) + list_query_path_and_name = [] + continue + if query_line.startswith("#"): + continue + m = re.match(r'\s*(.+)\s*,\s*(.+)\s*',query_line) + if m: + query_path, user_column_name = m.groups() + resultspec = makeResultSpec(query_path) + else: + query_path = query_line.strip() + resultspec = makeResultSpec(query_path) + user_column_name = "{ColumnName}/{RowName}".format(**asdict(resultspec)) + list_query_path_and_name.append((resultspec, user_column_name)) + if list_query_path_and_name != []: + listlist_query_path_and_name.append(list_query_path_and_name) + return listlist_query_path_and_name + +def build_query_with_special_cases(resultspec: ResultSpec, finalize = True) -> str: + """Returns SQLite query that can be executed to extract results from EnergyPlus tabular reports. + + Special cases: + For compatibility with modelkit queries, "Total Energy" is emulated as follows. + AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/X + translates to + AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/X where ColumnName <> Water. + + Inputs: + resultspec: ResultSpec + A ResultSpec object or modelkit-style query path to transform into an SQLite query. + finalize: bool, default True + Whether to terminate the query with a semicolon (;) + + Returns: + query: + SQLite query string (e.g. SELECT * from TabularDataWithStrings WHERE ...). + agg_columns: list[str] + List of columns in which the query includes a wildcard (*), useful to aggregate the results. + """ + TOKEN_ANY = '*' + #TABULAR_DATA_HEADERS = ['ReportName', 'ReportForString', + # 'TableName', 'ColumnName', 'RowName'] + + if not isinstance(resultspec, ResultSpec): + resultspec = makeResultSpec(resultspec) + + if resultspec.to_string().startswith("AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/Total Energy/"): + # Special case. 'Total Energy' is a synthetic result not defined by EnergyPlus. + # It is not a good idea to use this because it is adding quantities with different meanings (kWh electric + kWh gas, etc). + if resultspec.RowName == TOKEN_ANY: + query,agg_columns = build_query_with_special_cases( + "AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/*", + False) + query += """ AND ColumnName <> 'Water';""" + return query,agg_columns + else: + query,agg_columns = build_query_with_special_cases( + f"AnnualBuildingUtilityPerformanceSummary/Entire Facility/End Uses/*/{resultspec.RowName}", + False) + query += """ AND ColumnName <> 'Water';""" + return query,agg_columns + + agg_columns = ['ReportName'] + query = """SELECT * from TabularDataWithStrings + WHERE ReportName = :ReportName""" + + if (resultspec.ReportForString and resultspec.ReportForString != TOKEN_ANY): + query += " AND ReportForString = :ReportForString" + agg_columns.append('ReportForString') + + if (resultspec.TableName and resultspec.TableName != TOKEN_ANY): + query += " AND TableName = :TableName" + agg_columns.append('TableName') + + if (resultspec.ColumnName and resultspec.ColumnName != TOKEN_ANY): + query += " AND ColumnName = :ColumnName" + agg_columns.append('ColumnName') + + if (resultspec.RowName and resultspec.RowName != TOKEN_ANY): + query += " AND RowName = :RowName" + agg_columns.append('ReportForString') + + if finalize: + query += ";" + agg_columns.append('Units') + return query, agg_columns + + +def get_sim_hourly(conn: Connection): + """Get simulation hourly results from one EnergyPlus SQLite output file. + + Returns: + ReportDataWide: pandas.DataFrame + Table with shape (N,8760) where each of N rows represent an hourly variable + and each of 8760 columns represents one hour of an annual simulation period. + Names of hourly variables in the index column follow the EnergyPlus CSV output convention. + + Example + + >>> with connect('instance-out.sql') as conn: + ReportDataWide = get_hourly_results_deer(conn, 'CZ11') + >>> ReportDataWide + TimeIndex 1 2 8760 + LookupKey + Electricity:Facility [J](Hourly) 5.222829e+07 4.893178e+07 ... 5.366953e+07 + Environment:Site Outdoor Air Drybulb Temperature [C](Hourly) 5.358333e+00 5.841667e+00 ... 5.575000e+00 + + Technical details: + Implementation joins the ReportDataDictionary and ReportData tables. + LookupKey returned + Requires that the EnergyPlus model contains an OutputControl:Files object with SQLite = Yes. + """ + + ReportDataDictionary = pd.read_sql_query('select * from ReportDataDictionary', conn, index_col='ReportDataDictionaryIndex') + #n_rows, = conn.execute('select count(*) from ReportData').fetchone() + chunks = [] + for chunk in pd.read_sql_query('select * from ReportData', conn, chunksize=10000): + chunks.append(chunk) + ReportData = pd.concat(chunks, axis=0) + + # Transform ReportDataDictionary so we have a single column lookup string. + # LookupKey looks like: + # If 'EL7 NORTH PERIM ZN (G.N2):Zone Total Internal Total Heating Energy [J](Hourly)' + # LookupKey looks like 'EL7 NORTH PERIM ZN (G.N2):Zone Total Internal Total Heating Energy [J](Hourly)' + ReportDataDictionary['LookupKey']=ReportDataDictionary.apply( + lambda x: f'{x.KeyValue}:{x.Name} [{x.Units}]({x.ReportingFrequency})' if bool(x.KeyValue) + else f'{x.Name} [{x.Units}]({x.ReportingFrequency})' + , axis=1) + ReportData2 = ReportData.join(ReportDataDictionary, on='ReportDataDictionaryIndex') + + # Transform ReportData from long to wide so we can make a condensed table + ReportDataWide = ReportData2.pivot(index='LookupKey',columns='TimeIndex',values='Value') + # Prepare the table for saving in a database + #ReportDataWide['sim_id'] = sim_run.sim_id + #ReportDataWide2=ReportDataWide.reset_index().set_index(['TimeIndex'],drop=True) + + return ReportDataWide + +def get_sim_deer_peak(conn: Connection, bldgloc: str): + """Get simulation DEER Peak results from one EnergyPlus SQLite output file. + + Inputs: + conn: sqlite3.Connection + An open connection to the SQLite output file from an EnergyPlus simulation. + bldgloc: str + The CEC climate zone used to lookup up DEER peak period dates. + Returns: + deer_peak_values: dict + Lookup where each item `(k, v)` represents the average value `v` + of the hourly variable named `k` over the DEER Peak Period. + """ + # Get all available hourly results with shape (N, 8760) + ReportDataWide = get_sim_hourly(conn) + ReportDataWide = ReportDataWide.loc[DEERPEAK_COLUMNS] + if ReportDataWide.shape[1] != 8760: + # No hourly data. This can happen if simulation created the output file but failed to complete. + # Or if the file represents a sizing run. + return None + # Get 8760-length mask for DEER Peak Period (normalized) + dpm = get_deer_peak_multipliers(bldgloc) + # Compute the average value over the DEER Peak Period + # In testing, pandas.DataFrame.mul() takes about 1 ms + #deer_peak_values = ReportDataWide.mul(dpm,axis=1).sum(axis=1).to_dict() + # In testing, pandas.DataFrame.to_numpy().dot() takes about 7 µs + deer_peak_values = dict(zip(ReportDataWide.index, ReportDataWide.to_numpy().dot(dpm))) + return deer_peak_values + +def get_sim_tabular( + conn: Connection, + resultspec: ResultSpec, + aggtype = 'sum' + ) -> tuple: + """Returns result information based on a single query from tabular reports. + + Inputs: + conn: sqlite3.Connection + Open connection to the model instance results database (e.g. instance-out.sql) + + aggtype: str + Aggregation type, e.g. sum. Explains how to combine multiple values where + the query includes a wildcard (*). + + Returns (sim_data_detail, sim_data_agg) where: + sim_data_detail: pandas.DataFrame or None + DataFrame of raw results from the model, possibly including multiple rows in case of a wildcard. + sim_data_agg: float or None + Single value. In case of wildcard in query, this is calculated according to aggtype. + """ + if not isinstance(resultspec, ResultSpec): + resultspec = makeResultSpec(resultspec) + query, agg_columns = build_query_with_special_cases(resultspec) + + try: + sim_data_detail = pd.read_sql_query(query, conn, params=asdict(resultspec), dtype={'Value':float}) + except ValueError: + # If user requested a query that returns a string value + # To do: aggregation doesn't work with string type results. + sim_data_detail = pd.read_sql_query(query, conn, params=asdict(resultspec)) + + if sim_data_detail.empty: + # No data found matching result spec + return None, None + elif len(sim_data_detail) == 1: + # Only one value, no aggregation required + return sim_data_detail, sim_data_detail.loc[0,'Value'] + else: + # Aggregation requested. Calculate a single float value. + sim_data_agg = ( + sim_data_detail + .groupby(agg_columns) + ['Value'].agg(aggtype).iloc[0] + ) + return sim_data_detail, sim_data_agg + +def get_sim_peak_and_tabular(queryfile: Path, + sqlfile: Path, + bldgloc: str, + metadata: dict): + r""" + Read selected data entries from SQL outputs. + Result set specifications are parsed from query.txt, e.g. (resultspec, name). + Output columns will have units appended to name, like "name (Units)". + + Inputs: + queryfile: Path + The filename of a modelkit-style query.txt file. + sqlfile: Path + The filename of an EnergyPlus output file (SQLite format). + bldgloc: str + The CEC climate zone, e.g. CZ01 through CZ16. + metadata: dict + An dictionary of identifier information prepended to the results. + For compatibility use metadata = {'File Name': 'path/to/model/instance-out.sql'} + + Returns: + sim_data: dict(str: float | None). + Mapping of (name, value) from both query results + and hourly averages over the DEER peak period. + """ + sim_data = metadata.copy() # To store results + with connect(sqlfile) as conn: + # Start with the query data results + listlist_query_path_and_name = parse_query_file(queryfile) + # Don't separate "groups" of queries but group them all together. + # result_sets = [] + for list_query_path_and_name in listlist_query_path_and_name: + # Don't separate "groups" of queries but group them all together. + # sim_data_detail, sim_data_agg = [], [] + for resultspec, user_column_name in list_query_path_and_name: + # 2025-01-22 Updated Nicholas Fette + # Default to the column name from the result query without attempting to append unit symbol from results. + # This avoids errors due to mismatched column names when a file is missing one or more results. + # Useful for concatenating results in a wide-format table. + output_column_name = user_column_name + + if APPEND_UNITS: + # For consistency between files, do not append "(units)" in the column name for wildcard queries. + if "*" not in resultspec.to_string() and sim_data_detail1 is not None: + units = sim_data_detail1['Units'].iloc[0] + output_column_name = f"{user_column_name} ({units})" + + sim_data_detail1, sim_data_agg1 = get_sim_tabular(conn, resultspec) + if sim_data_detail1 is None: + # No data found matching the result spec. + # 2025-01-22 Updated Nicholas Fette + # For consistency between files, store a None/NULL result for this column. + # To-do: In sqlite output mode, pandas may not be able to guess the dtype. + # As a workaround, user may manually alter the sim_data table column types, then run the script. + sim_data.update({output_column_name: None}) + continue + # This script does not compile detail of all rows included in wildcard queries: + #sim_data_detail.append(sim_data_detail1) + if sim_data_agg1 is not None: + sim_data.update({output_column_name: sim_data_agg1}) + #sim_data_agg.append(sizing_agg_row) + + # Now get the DEER Peak values from hourly data + # Column name(s) for DEER Peak average values are taken directly from hourly output column name. + deer_peak_values = get_sim_deer_peak(conn, bldgloc) + if deer_peak_values is not None: + sim_data.update(deer_peak_values) + + return sim_data + +def get_runs_instances(study: Path, search_pattern = '**/instance*-out.sql', exclude = 'instance-size-out.sql'): + r"""Returns a list of all of SQLite output files in a modelkit study folder. + + Assumes that files are placed within a "runs" subfolder under the given study. + + Inputs: + study: pathlib.Path + The folder in which to search for simulation outputs. + E.g. old style: "C:\Users\User1\DEER-Prototypes-EnergyPlus\Analysis\SFm_Furnace_1975" + E.g. new style: "C:\Users\User1\DEER-Prototypes-EnergyPlus\commercial measures\SWHC012-04 Occupancy Sensor" + search_pattern: str, default = 'instance*-out.sql' + The filename pattern used to search for output files, using glob syntax. + exclude_pattern: str, default = 'instance-size-out.sql' + A filename pattern to exclude. + + Returns: list of tuples (sqlfile, bldgloc, metadata) where + sqlfile: pathlib.Path + An EnergyPlus SQLite output file found in the study folder. + bldgloc: str + CEC Climate zone found in file name. + metadata: dict + + Default metadata fields: + 'File Name' + File path relative to study folder, with forward slashes. + """ + if not isinstance(study, Path): + study = Path(study) + # Note that autosized runs are named instance-out.sql. + # Linked-sizing runs are named instance-hardsize-out.sql. + # Sizing-only runs are named instance-size-out.sql. + for sqlfile in study.glob(search_pattern): + if sqlfile.match(exclude): + continue + relpath = sqlfile.relative_to(study) + # E.g. relpath = Path(r"runs\CZ01\SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace\Msr-Res-GasFurnace-AFUE95-ECM\instance-out.sql") + relstr = relpath.as_posix() # with forward slashes + # E.g. relstr = "runs/CZ01/SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace/Msr-Res-GasFurnace-AFUE95-ECM/instance-out.sql" + # Search string for climate zone like 'CZ11/'. + m = re.search(r"CZ\d\d(?=/)", relstr) + if not m: + raise ValueError(f'Could not match climate zone in filename: "{relstr}"') + bldgloc = m[0] + + metadata = {} + # For compatibility with modelkit, may want to remove 'runs/' prefix. + # E.g. filename = "CZ01/SFm&1&rDXGF&Ex&SpaceHtg_eq__GasFurnace/Msr-Res-GasFurnace-AFUE95-ECM/instance-out.sql" + # pathsub = (r'runs/','') + #metadata['File Name'] = re.sub(*pathsub, relstr, 1) + metadata['File Name'] = relstr + metadata['BldgLoc'] = bldgloc + + # Try to get additional metadata, but don't fail if it doesn't match. + patterns = [ + r'.*/runs[^/]*/(?PCZ\d\d)/(?P\w+)&(?P\w+)&(?P\w+)&(?P\w+)&(?P\w+)__(?P\w+)/(?P[^/]+)/instance.*', + r'.*/runs[^/]*/(?PCZ\d\d)/(?P[^/]+)/(?P[^/]+)/instance.*' + ] + for pattern in patterns: + m2 = re.match(pattern, relstr) + if m2: + metadata.update(m2.groupdict()) + break + + yield (sqlfile, bldgloc, metadata) + +def gather_sim_data(study: Path, queryfile: Path, parallel=False): + r"""Returns a generator yielding simulation data from each simulation. + + Read selected data entries from SQL outputs as well as DEER Peak period averages of hourly variables. + Result set specifications are parsed from query.txt, e.g. (resultspec, name). + Output columns will have units appended to name, like "name (Units)". + + Assumes that files are placed within a "runs" subfolder under the given study. + + study: e.g., "C:\Users\User1\DEER-Prototypes-EnergyPlus\Analysis\SFm_Furnace_1975" + + Returns: + Generator yielding dictionary objects. + + Example: + >>> for sim_data in gather_sim_data(sqlfile, queryfile): + >>> pass + >>> sim_data + { + "File Name": "mymeasure_vintage/CZ01/cohort/case/instance-out.sql", + "Net Site EUI (kWh/m2)": 90.97, + "Electricity:Facility [J](Hourly)": 3738615573 + } + """ + print(f"Reading from {study}") + # Make sure queryfile does not give an error before starting main loop. + _ = parse_query_file(queryfile) + + if not parallel: + for sqlfile, bldgloc, metadata in tqdm.tqdm(list(get_runs_instances(study))): + # Start the load operations and mark each future with its input arguments. + yield get_sim_peak_and_tabular(queryfile, sqlfile, bldgloc, metadata) + else: + list_sqlfile = list(get_runs_instances(study)) + # Use a concurrent.futures.Executor to achieve some parallelism. + # This should speed up the process if there are a large number of files. + # In initial testing, ThreadPoolExecutor was 0.5x the speed of a single-threaded loop. + # However, ProcessPoolExecutor was 3-4x the speed of a single-threaded loop. + #with concurrent.futures.ThreadPoolExecutor() as executor: + with concurrent.futures.ProcessPoolExecutor() as executor: + #print("Created a thread pool with ",executor._max_workers) + future_lookup = dict() # Remember each file when requested. + # Queue each operation to read simulation data, returning a future. + for (sqlfile, bldgloc, metadata) in list_sqlfile: + # Start the load operations and mark each future with its input arguments. + future = executor.submit(get_sim_peak_and_tabular, queryfile, sqlfile, bldgloc, metadata) + future_lookup[future] = (sqlfile, bldgloc, metadata) + + # Wait for futures to complete and show a progress bar. + import time + for i,future in zip( + tqdm.trange(len(list_sqlfile), desc=study.name), # progress bar + concurrent.futures.as_completed(future_lookup) # waiting for results from parallel threads + ): + (sqlfile, bldgloc, metadata) = future_lookup[future] + try: + sim_data = future.result() + except Exception as exc: + print(f'Reading {sqlfile} generated an exception: {exc}') + else: + yield sim_data + time.sleep(0.001) + +def gather_sim_data_to_csv(study: Path, queryfile: Path, csvfile: Path, + parallel = True, + chunksize = 100): + # 2024-05-15 Todo + # User testing observed that inconsistent filenames may result in inconsistent + # column alignment in CSV mode. Workaround is to change chunksize=None. + gather = gather_sim_data(study, queryfile, parallel) + with open(csvfile, 'w', newline='') as f: + if chunksize is None: + # Get all records at once to gaurantee headers are the same for all rows + records = list(gather) + df_sim_data = pd.DataFrame.from_records(records) + df_sim_data.to_csv(f, index=False) + else: + for i,records in enumerate(batched(gather, chunksize)): + df_sim_data = pd.DataFrame.from_records(records) + df_sim_data.to_csv(f, index=False, header=(i==0)) + +def gather_sim_data_to_sqlite(study: Path, queryfile: Path, sqlfile: Path, + parallel = True, + chunksize = 100): + gather = gather_sim_data(study, queryfile, parallel) + with connect(sqlfile) as conn: + conn.execute('DROP TABLE IF EXISTS "sim_data";') + if chunksize is None: + # Get all records at once to gaurantee headers are the same for all rows + records = list(gather) + df_sim_data = pd.DataFrame.from_records(records) + df_sim_data.to_sql('sim_data', conn, index=False) + else: + for i,records in enumerate(batched(gather, chunksize)): + df_sim_data = pd.DataFrame.from_records(records) + df_sim_data.to_sql('sim_data', conn, index=False, if_exists='append') + +def build_cli_parser(parser: argparse.ArgumentParser, + study_kwargs = {}, + queryfile_kwargs = {}, + #outputfile_kwargs = {} + ): + parser.add_argument('study', type=Path, nargs='?', default='.', + help=r'Analysis subfolder, e.g. C:\Users\user1\Desktop\DEER-EnergyPlus-Prototypes\Analysis\SFm_Furnace_1975', + **study_kwargs) + parser.add_argument('-q','--queryfile', type=Path, default='query.txt', + help=r'Query file, e.g. query.txt', + **queryfile_kwargs) + #parser.add_argument('-o','--output', type=Path, default='simdata.csv', + # help=r'Output file, e.g. simdata.csv', + # **outputfile_kwargs) + parser.add_argument('-P', '--parallel', action='store_false', help='Disable parallel mode.') + parser.add_argument('-s', '--sqlite', action='store_true', help='Write output in SQLite format.') + +def cli_main(): + """Starts the script on command line.""" + parser = argparse.ArgumentParser() + build_cli_parser(parser) + pargs = parser.parse_args() + if pargs.sqlite: + gather_sim_data_to_sqlite(pargs.study, pargs.queryfile, 'simdata.sqlite', pargs.parallel) + else: + gather_sim_data_to_csv(pargs.study, pargs.queryfile, 'simdata.csv', pargs.parallel) + +def gooey_main(): + """Opens a window for user to input options and start the script.""" + import gooey + parser = gooey.GooeyParser() + # Gooey is not compatible with Tqdm progress bar without more changes. + build = gooey.Gooey(build_cli_parser, progress_regex=r"\| (?P\d+)/(?P\d+) \[") + build(parser, + study_kwargs = dict(widget='DirChooser'), + queryfile_kwargs = dict(widget='FileChooser'), + #outputfile_kwargs = dict(widget='FileChooser') + ) + pargs = parser.parse_args() + if pargs.sqlite: + gather_sim_data_to_sqlite(pargs.study, pargs.queryfile, 'simdata.sqlite', pargs.parallel) + else: + gather_sim_data_to_csv(pargs.study, pargs.queryfile, 'simdata.csv', pargs.parallel) + +def test(): + """Starts the script with hard-coded options.""" + #study = Path(r'C:\DEER2026\SWHC012-nick\commercial measures\SWHC012-04 Occupancy Sensor') + study = Path(r'C:\DEER2026\nf_com_testing_dhw\commercial measures\SWXX000-00 Measure Name') + queryfile = Path(r'..\querylibrary\query_default.txt') + gather_sim_data_to_csv(study, queryfile, 'simdata.csv', parallel=False) + +if "__main__" == __name__: + cli_main() + #gooey_main() + #test() diff --git a/templates/energyplus/templates/custom.pxt b/templates/energyplus/templates/custom.pxt index 16fb0240..e52024a3 100644 --- a/templates/energyplus/templates/custom.pxt +++ b/templates/energyplus/templates/custom.pxt @@ -55,3 +55,14 @@ Output:Meter,Gas:Facility,hourly; !- [J] !Output:Variable,<%= regex %> Node,System Node Standard Density Volume Flow Rate,hourly; !- HVAC Average [kg/s] !Output:Variable,<%= regex %> Node,System Node Temperature,hourly; !- HVAC Average [C] + +! Solaris Technical 2024. Output variables for testing and debugging SWHC008 VSD Central Plant. +!Output:Variable, +! *, !- Key Value +! Pump Mass Flow Rate, !- Variable Name +! Hourly; !- Reporting Frequency + +!Output:Variable, +! *, !- Key Value +! Cooling Tower Mass Flow Rate, !- Variable Name +! Hourly; !- Reporting Frequency diff --git a/templates/energyplus/templates/system/cw.pxt b/templates/energyplus/templates/system/cw.pxt index 952feed9..74631dd2 100644 --- a/templates/energyplus/templates/system/cw.pxt +++ b/templates/energyplus/templates/system/cw.pxt @@ -3,6 +3,10 @@ parameter "name" parameter "branch_names" parameter "tower_type", :default=>"VARIABLESPEED" # (VARIABLESPEED | SINGLESPEED) + +#Solaris Technical - Behzad S. Rizi - 11/11/2025 - Added pump_type parameter to enable the speed control strategy for condenser water pump +parameter "pump_type", :default=>nil # (CONSTANTSPEED | VARIABLESPEED) + parameter "num_towers", :default=>1 parameter "design_temp", :default=>85['F'] # Condenser water system supply temperature parameter "design_delta", :default=>10['deltaF'] # Condenser water system design temperature difference @@ -24,6 +28,20 @@ parameter "wetbulb_design", :default=>25.6['C'] parameter "operation_schedule", :default => "Through: 12/31,\n For: AllDays,\n Until: 24:00, 1;" parameter "clear_water_supply_tank", :default=>"" + +# 2025-10-31 Nicholas Fette. To allow user control over condenser pump control type. +parameter "pump_control_type", :default=>"Intermittent" # (Intermittent | Continuous) + +# 2024-02-07 Afshin Faramarzi. To specify condenser pump minimum mass flow rate in conjunction with continuous pump control. +# Note that modelkit caboodle does not have any unit conversions for mass flow rate. +parameter "pump_min_flow_rate", :default=>0 # (kg/s) +parameter "min_flowrate_fraction", :default=>0 + +%> + +<%# Solaris Technical - Behzad S. Rizi - 11/11/2025 - Default assignment: if pump_type not provided, set to "VARIABLESPEED" for multi-tower systems and "CONSTANTSPEED" otherwise (legacy behavior) %> +<% + pump_type ||= (num_towers > 1 ? "VARIABLESPEED" : "CONSTANTSPEED") %> Sizing:Plant, @@ -49,7 +67,7 @@ CondenserLoop, 80.0, !- Maximum Loop Temperature {C} 5.0, !- Minimum Loop Temperature {C} Autosize, !- Maximum Loop Flow Rate {m3/s} - 0.0, !- Minimum Loop Flow Rate {m3/s} + 0, !- Minimum Loop Flow Rate {m3/s} Autosize, !- Condenser Loop Volume {m3} <%= name %> Supply Inlet Node, !- Condenser Side Inlet Node Name <%= name %> Supply Outlet Node, !- Condenser Side Outlet Node Name @@ -118,6 +136,96 @@ SetpointManager:FollowOutdoorAirTemperature, ! Until: 24:00, !- Field 3 ! <%= design_temp %>; !- Field 4 +<%# 2024-02-07 Afshin Faramarzi +Setpoint manager and schedule to keep condenser pump at least 70% of rated mass flow rate. +User to specify flow rate based on prior simulation results. +%> + + +!------------------------------------------------------------------------------ +! 2025-12-02, Solaris Technical, Behzad S. Rizi +! Condenser Water Loop Minimum Flow Control (EMS + Setpoint Manager) +! +! Purpose: +! EnergyPlus does not automatically enforce a system-level minimum flow rate +! for condenser water loops when variable-speed pumps are used. Many chiller +! and cooling tower manufacturers require a minimum condenser water flow +! (typically 60–80% of design flow) to maintain stable heat rejection and +! to avoid equipment operating outside of allowable limits. +! +! For CPUC measure compliance, a minimum flow of 70% of the autosized design +! condenser water loop flow is required whenever cooling load exists. +! +! Method: +! 1. A Schedule:Constant object is created to store the minimum flow rate. +! 2. A SetpointManager:Scheduled applies this schedule to the condenser loop +! supply outlet node using the "MinimumMassFlowRate" control variable. +! This is the only legal mechanism in EnergyPlus to enforce minimum loop flow. +! 3. EMS Sensors read actual loop mass flow and loop ΔT. +! 4. An EMS Program updates the schedule dynamically: +! - when cooling load exists (ΔT > 0.2C), set schedule to 70% design flow +! - when no load exists, set schedule to 0 (allowing pump turnoff) +! +! Notes: +! - EMS cannot control bypass branches or piping; EnergyPlus does not expose +! actuators for Branch or Pipe objects. Therefore, minimum flow can only be +! enforced at the plant loop level via the Setpoint Manager. +! - This control method does not modify prototype topology and is compatible +! with all other measure packages. +! +! Result: +! Ensures condenser water loop flow does not fall below 70% of design flow +! during operation, consistent with real-world equipment requirements and +! CPUC savings methodology. +!------------------------------------------------------------------------------ + + +Schedule:Constant, + <%= name %> Pump Min Flow Sch, !- Name + Any Number, !- Schedule Type Limits Name + 0.0; !- Initial Value + +SetpointManager:Scheduled, + <%= name %> Pump Setpoint Manager, !- Name + MinimumMassFlowRate, !- Control Variable + <%= name %> Pump Min Flow Sch, !- Schedule Name + <%= name %> Supply Outlet Node; !- Setpoint Node (SYSTEM FLOW CONTROL) + +EnergyManagementSystem:Sensor, + CondenserLoopFlow, + <%= name %> Supply Outlet Node, + System Node Mass Flow Rate; + +EnergyManagementSystem:Sensor, + CondenserLoopTempIn, + <%= name %> Supply Inlet Node, + System Node Temperature; + +EnergyManagementSystem:Sensor, + CondenserLoopTempOut, + <%= name %> Supply Outlet Node, + System Node Temperature; + +EnergyManagementSystem:Actuator, + PumpMinFlowActuator, !- Name + <%= name %> Pump Min Flow Sch, !- Actuated Component Unique Name + Schedule:Constant, !- Actuated Component Type + Schedule Value; !- Actuated Component Control Type + +EnergyManagementSystem:Program, + CondenserPumpMinFlowControl, + SET dT = CondenserLoopTempIn - CondenserLoopTempOut, + IF (CondenserLoopFlow > 0.0001) && (dT > 0.2), + SET PumpMinFlowActuator = <%= pump_min_flow_rate %>, + ELSE, + SET PumpMinFlowActuator = 0.0, + ENDIF; + +EnergyManagementSystem:ProgramCallingManager, + CondenserPumpMinFlowCallingMgr, + InsideHVACSystemIterationLoop, + CondenserPumpMinFlowControl; + CondenserEquipmentOperationSchemes, <%= name %> Operation Schemes, !- Name <% if (heat_addition) %> @@ -183,11 +291,17 @@ BranchList, <%= name %> Supply Equipment Bypass Branch, !- Branch Name <%= name %> Supply Outlet Branch; !- Branch Name - +! --------------------------------------------------------------------------- +! Solaris-Technical - Behzad S. Rizi - 11/11/2025 - New parameter added to control condenser water pump speed independently of tower type +! Condenser Water Pump Configuration +! Controlled independently of cooling tower type. +! This supports modeling of “VFD on condenser water pump” measures without +! modifying cooling tower fan control or tower configuration. +! --------------------------------------------------------------------------- Branch, <%= name %> Supply Inlet Branch, !- Name , !- Pressure Drop Curve Name -<% if num_towers > 1 %> +<% if pump_type == "VARIABLESPEED" %> HeaderedPumps:VariableSpeed, !- Component 1 Object Type <% else %> Pump:ConstantSpeed, !- Component 1 Object Type @@ -196,7 +310,8 @@ Branch, <%= name %> Supply Inlet Node, !- Component 1 Inlet Node Name <%= name %> Pump Outlet Node; !- Component 1 Outlet Node Name -<% if num_towers > 1 %> + +<% if pump_type == "VARIABLESPEED" %> HeaderedPumps:VariableSpeed, <%= name %> Pump, !- Name <%= name %> Supply Inlet Node, !- Inlet Node Name @@ -212,8 +327,8 @@ HeaderedPumps:VariableSpeed, 0.0216, !- Coefficient 2 of the Part Load Performance Curve -0.0325, !- Coefficient 3 of the Part Load Performance Curve 1.0095, !- Coefficient 4 of the Part Load Performance Curve - 0, !- Minimum Flow Rate Fraction - Intermittent; !- Pump Control Type + <%= min_flowrate_fraction %>, !- Minimum Flow Rate Fraction + <%= pump_control_type %>; !- Pump Control Type <% else %> Pump:ConstantSpeed, <%= name %> Pump, !- Name @@ -224,7 +339,7 @@ Pump:ConstantSpeed, Autosize, !- Rated Power Consumption {W} <%= pump_eff %>, !- Motor Efficiency 0.0, !- Fraction of Motor Inefficiencies to Fluid Stream - Intermittent; !- Pump Control Type + <%= pump_control_type %>; !- Pump Control Type <% end %> @@ -615,3 +730,4 @@ Connector:Mixer, <%= branch_name %> HR Demand Branch, !- Inlet Branch Name <% end %> <%= name %> Demand Bypass Branch; !- Inlet Branch Name + \ No newline at end of file