ecoengine 3.0.1__tar.gz → 3.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. {ecoengine-3.0.1 → ecoengine-3.0.2}/PKG-INFO +1 -1
  2. ecoengine-3.0.2/README.md +183 -0
  3. {ecoengine-3.0.1 → ecoengine-3.0.2}/pyproject.toml +1 -1
  4. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/interfaces/EcosizerEngine.py +12 -17
  5. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/interfaces/Simulator.py +4 -2
  6. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/storage/StratifiedTank.py +3 -8
  7. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/DHWSystem.py +81 -37
  8. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/recirc_systems/ParallelLoopSystem.py +0 -1
  9. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/recirc_systems/SwingSystem.py +11 -4
  10. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/rtp_systems/MultiPassRTPSystem.py +16 -7
  11. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/rtp_systems/RTPSystem.py +14 -4
  12. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/rtp_systems/SinglePassRTPSystem.py +6 -4
  13. ecoengine-3.0.2/src/ecoengine/objects/dhwsystems/utils.py +23 -0
  14. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/simulation/SimulationRun.py +16 -3
  15. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/tests/test_dhw_system.py +16 -4
  16. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/tests/test_storage_tanks.py +74 -0
  17. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine.egg-info/PKG-INFO +1 -1
  18. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine.egg-info/SOURCES.txt +1 -0
  19. ecoengine-3.0.1/src/ecoengine/objects/dhwsystems/utils.py +0 -20
  20. {ecoengine-3.0.1 → ecoengine-3.0.2}/setup.cfg +0 -0
  21. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/__init__.py +0 -0
  22. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/constants/__init__.py +0 -0
  23. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/constants/constants.py +0 -0
  24. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/__init__.py +0 -0
  25. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/climate_data/DryBulbTemperatures_ByClimateZone.csv +0 -0
  26. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/climate_data/InletWaterTemperatures_ByClimateZone.csv +0 -0
  27. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/climate_data/WeatherStation_ClimateZone_Lookup.csv +0 -0
  28. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/climate_data/ZipCode_ClimateZone_Lookup.csv +0 -0
  29. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/climate_data/__init__.py +0 -0
  30. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/climate_data/kGperkWh_ByClimateZone.csv +0 -0
  31. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/__init__.py +0 -0
  32. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/apartment.json +0 -0
  33. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/elementary_school.json +0 -0
  34. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/food_service_a.json +0 -0
  35. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/food_service_b.json +0 -0
  36. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/junior_high.json +0 -0
  37. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/mens_dorm.json +0 -0
  38. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/motel.json +0 -0
  39. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/multi_family.json +0 -0
  40. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/nursing_home.json +0 -0
  41. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/office_building.json +0 -0
  42. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/senior_high.json +0 -0
  43. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/load_shapes/womens_dorm.json +0 -0
  44. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/__init__.py +0 -0
  45. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/maps.json +0 -0
  46. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/COLMAC_R454B_Single_Pass_bounds.pkl +0 -0
  47. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/COLMAC_R454B_Single_Pass_capacity_interpolator.pkl +0 -0
  48. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/COLMAC_R454B_Single_Pass_power_in_interpolator.pkl +0 -0
  49. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Multi_Pass_bounds.pkl +0 -0
  50. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Multi_Pass_capacity_interpolator.pkl +0 -0
  51. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Multi_Pass_power_in_interpolator.pkl +0 -0
  52. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Oversized_Condenser_Multi_Pass_bounds.pkl +0 -0
  53. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Oversized_Condenser_Multi_Pass_capacity_interpolator.pkl +0 -0
  54. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Oversized_Condenser_Multi_Pass_power_in_interpolator.pkl +0 -0
  55. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Oversized_Condenser_Single_Pass_bounds.pkl +0 -0
  56. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Oversized_Condenser_Single_Pass_capacity_interpolator.pkl +0 -0
  57. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Oversized_Condenser_Single_Pass_power_in_interpolator.pkl +0 -0
  58. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Single_Pass_bounds.pkl +0 -0
  59. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Single_Pass_capacity_interpolator.pkl +0 -0
  60. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_Single_Pass_power_in_interpolator.pkl +0 -0
  61. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_VFD_45_Hz_Multi_Pass_bounds.pkl +0 -0
  62. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_VFD_45_Hz_Multi_Pass_capacity_interpolator.pkl +0 -0
  63. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_VFD_45_Hz_Multi_Pass_power_in_interpolator.pkl +0 -0
  64. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_VFD_45_Hz_Single_Pass_bounds.pkl +0 -0
  65. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_VFD_45_Hz_Single_Pass_capacity_interpolator.pkl +0 -0
  66. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_VFD_45_Hz_Single_Pass_power_in_interpolator.pkl +0 -0
  67. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_VFD_60_Hz_Single_Pass_bounds.pkl +0 -0
  68. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_VFD_60_Hz_Single_Pass_capacity_interpolator.pkl +0 -0
  69. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA10_VFD_60_Hz_Single_Pass_power_in_interpolator.pkl +0 -0
  70. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_Multi_Pass_bounds.pkl +0 -0
  71. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_Multi_Pass_capacity_interpolator.pkl +0 -0
  72. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_Multi_Pass_power_in_interpolator.pkl +0 -0
  73. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_Oversized_Condenser_Multi_Pass_bounds.pkl +0 -0
  74. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_Oversized_Condenser_Multi_Pass_capacity_interpolator.pkl +0 -0
  75. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_Oversized_Condenser_Multi_Pass_power_in_interpolator.pkl +0 -0
  76. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_Multi_Pass_bounds.pkl +0 -0
  77. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_Multi_Pass_capacity_interpolator.pkl +0 -0
  78. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_Multi_Pass_power_in_interpolator.pkl +0 -0
  79. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_Single_Pass_bounds.pkl +0 -0
  80. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_Single_Pass_capacity_interpolator.pkl +0 -0
  81. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_Single_Pass_power_in_interpolator.pkl +0 -0
  82. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_VFD_45_Hz_Multi_Pass_bounds.pkl +0 -0
  83. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_VFD_45_Hz_Multi_Pass_capacity_interpolator.pkl +0 -0
  84. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_VFD_45_Hz_Multi_Pass_power_in_interpolator.pkl +0 -0
  85. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_VFD_45_Hz_Single_Pass_bounds.pkl +0 -0
  86. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_VFD_45_Hz_Single_Pass_capacity_interpolator.pkl +0 -0
  87. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_R513a_VFD_45_Hz_Single_Pass_power_in_interpolator.pkl +0 -0
  88. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_Single_Pass_bounds.pkl +0 -0
  89. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_Single_Pass_capacity_interpolator.pkl +0 -0
  90. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_Single_Pass_power_in_interpolator.pkl +0 -0
  91. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_VFD_45_Hz_Multi_Pass_bounds.pkl +0 -0
  92. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_VFD_45_Hz_Multi_Pass_capacity_interpolator.pkl +0 -0
  93. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_VFD_45_Hz_Multi_Pass_power_in_interpolator.pkl +0 -0
  94. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_VFD_45_Hz_Single_Pass_bounds.pkl +0 -0
  95. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_VFD_45_Hz_Single_Pass_capacity_interpolator.pkl +0 -0
  96. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA15_VFD_45_Hz_Single_Pass_power_in_interpolator.pkl +0 -0
  97. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Multi_Pass_bounds.pkl +0 -0
  98. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Multi_Pass_capacity_interpolator.pkl +0 -0
  99. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Multi_Pass_power_in_interpolator.pkl +0 -0
  100. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Oversized_Condenser_Multi_Pass_bounds.pkl +0 -0
  101. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Oversized_Condenser_Multi_Pass_capacity_interpolator.pkl +0 -0
  102. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Oversized_Condenser_Multi_Pass_power_in_interpolator.pkl +0 -0
  103. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Oversized_Condenser_Single_Pass_bounds.pkl +0 -0
  104. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Oversized_Condenser_Single_Pass_capacity_interpolator.pkl +0 -0
  105. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Oversized_Condenser_Single_Pass_power_in_interpolator.pkl +0 -0
  106. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Single_Pass_bounds.pkl +0 -0
  107. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Single_Pass_capacity_interpolator.pkl +0 -0
  108. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_Single_Pass_power_in_interpolator.pkl +0 -0
  109. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_VFD_35_Hz_Multi_Pass_bounds.pkl +0 -0
  110. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_VFD_35_Hz_Multi_Pass_capacity_interpolator.pkl +0 -0
  111. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_VFD_35_Hz_Multi_Pass_power_in_interpolator.pkl +0 -0
  112. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_VFD_35_Hz_Single_Pass_bounds.pkl +0 -0
  113. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_VFD_35_Hz_Single_Pass_capacity_interpolator.pkl +0 -0
  114. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA20_VFD_35_Hz_Single_Pass_power_in_interpolator.pkl +0 -0
  115. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Multi_Pass_bounds.pkl +0 -0
  116. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Multi_Pass_capacity_interpolator.pkl +0 -0
  117. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Multi_Pass_power_in_interpolator.pkl +0 -0
  118. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Oversized_Condenser_Multi_Pass_bounds.pkl +0 -0
  119. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Oversized_Condenser_Multi_Pass_capacity_interpolator.pkl +0 -0
  120. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Oversized_Condenser_Multi_Pass_power_in_interpolator.pkl +0 -0
  121. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Oversized_Condenser_Single_Pass_bounds.pkl +0 -0
  122. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Oversized_Condenser_Single_Pass_capacity_interpolator.pkl +0 -0
  123. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Oversized_Condenser_Single_Pass_power_in_interpolator.pkl +0 -0
  124. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Single_Pass_bounds.pkl +0 -0
  125. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Single_Pass_capacity_interpolator.pkl +0 -0
  126. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_Single_Pass_power_in_interpolator.pkl +0 -0
  127. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_VFD_35_Hz_Multi_Pass_bounds.pkl +0 -0
  128. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_VFD_35_Hz_Multi_Pass_capacity_interpolator.pkl +0 -0
  129. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_VFD_35_Hz_Multi_Pass_power_in_interpolator.pkl +0 -0
  130. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_VFD_35_Hz_Single_Pass_bounds.pkl +0 -0
  131. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_VFD_35_Hz_Single_Pass_capacity_interpolator.pkl +0 -0
  132. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA25_VFD_35_Hz_Single_Pass_power_in_interpolator.pkl +0 -0
  133. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Multi_Pass_bounds.pkl +0 -0
  134. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Multi_Pass_capacity_interpolator.pkl +0 -0
  135. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Multi_Pass_power_in_interpolator.pkl +0 -0
  136. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Oversized_Condenser_Multi_Pass_bounds.pkl +0 -0
  137. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Oversized_Condenser_Multi_Pass_capacity_interpolator.pkl +0 -0
  138. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Oversized_Condenser_Multi_Pass_power_in_interpolator.pkl +0 -0
  139. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Oversized_Condenser_Single_Pass_bounds.pkl +0 -0
  140. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Oversized_Condenser_Single_Pass_capacity_interpolator.pkl +0 -0
  141. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Oversized_Condenser_Single_Pass_power_in_interpolator.pkl +0 -0
  142. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_Multi_Pass_bounds.pkl +0 -0
  143. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_Multi_Pass_capacity_interpolator.pkl +0 -0
  144. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_Multi_Pass_power_in_interpolator.pkl +0 -0
  145. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_Single_Pass_bounds.pkl +0 -0
  146. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_Single_Pass_capacity_interpolator.pkl +0 -0
  147. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_Single_Pass_power_in_interpolator.pkl +0 -0
  148. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_VFD_35_Hz_Multi_Pass_bounds.pkl +0 -0
  149. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_VFD_35_Hz_Multi_Pass_capacity_interpolator.pkl +0 -0
  150. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_VFD_35_Hz_Multi_Pass_power_in_interpolator.pkl +0 -0
  151. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_VFD_35_Hz_Single_Pass_bounds.pkl +0 -0
  152. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_VFD_35_Hz_Single_Pass_capacity_interpolator.pkl +0 -0
  153. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_R513a_VFD_35_Hz_Single_Pass_power_in_interpolator.pkl +0 -0
  154. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Single_Pass_bounds.pkl +0 -0
  155. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Single_Pass_capacity_interpolator.pkl +0 -0
  156. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_Single_Pass_power_in_interpolator.pkl +0 -0
  157. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_VFD_35_Hz_Multi_Pass_bounds.pkl +0 -0
  158. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_VFD_35_Hz_Multi_Pass_capacity_interpolator.pkl +0 -0
  159. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_VFD_35_Hz_Multi_Pass_power_in_interpolator.pkl +0 -0
  160. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_VFD_35_Hz_Single_Pass_bounds.pkl +0 -0
  161. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_VFD_35_Hz_Single_Pass_capacity_interpolator.pkl +0 -0
  162. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxA30_VFD_35_Hz_Single_Pass_power_in_interpolator.pkl +0 -0
  163. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_45_Hz_Multi_Pass_bounds.pkl +0 -0
  164. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_45_Hz_Multi_Pass_capacity_interpolator.pkl +0 -0
  165. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_45_Hz_Multi_Pass_power_in_interpolator.pkl +0 -0
  166. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_45_Hz_Single_Pass_bounds.pkl +0 -0
  167. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_45_Hz_Single_Pass_capacity_interpolator.pkl +0 -0
  168. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_45_Hz_Single_Pass_power_in_interpolator.pkl +0 -0
  169. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_60_Hz_Multi_Pass_bounds.pkl +0 -0
  170. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_60_Hz_Multi_Pass_capacity_interpolator.pkl +0 -0
  171. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_60_Hz_Multi_Pass_power_in_interpolator.pkl +0 -0
  172. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_60_Hz_Single_Pass_bounds.pkl +0 -0
  173. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_60_Hz_Single_Pass_capacity_interpolator.pkl +0 -0
  174. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV15_VFD_60_Hz_Single_Pass_power_in_interpolator.pkl +0 -0
  175. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV5_Multi_Pass_bounds.pkl +0 -0
  176. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV5_Multi_Pass_capacity_interpolator.pkl +0 -0
  177. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV5_Multi_Pass_power_in_interpolator.pkl +0 -0
  178. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV5_Single_Pass_bounds.pkl +0 -0
  179. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV5_Single_Pass_capacity_interpolator.pkl +0 -0
  180. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_CxV5_Single_Pass_power_in_interpolator.pkl +0 -0
  181. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_Multi_Pass_bounds.pkl +0 -0
  182. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_Multi_Pass_capacity_interpolator.pkl +0 -0
  183. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_Multi_Pass_power_in_interpolator.pkl +0 -0
  184. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_R513a_Multi_Pass_bounds.pkl +0 -0
  185. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_R513a_Multi_Pass_capacity_interpolator.pkl +0 -0
  186. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_R513a_Multi_Pass_power_in_interpolator.pkl +0 -0
  187. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_R513a_Single_Pass_bounds.pkl +0 -0
  188. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_R513a_Single_Pass_capacity_interpolator.pkl +0 -0
  189. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_R513a_Single_Pass_power_in_interpolator.pkl +0 -0
  190. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_Single_Pass_bounds.pkl +0 -0
  191. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_Single_Pass_capacity_interpolator.pkl +0 -0
  192. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Colmac_HPA4_Single_Pass_power_in_interpolator.pkl +0 -0
  193. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Droplet_Single_Pass_bounds.pkl +0 -0
  194. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Droplet_Single_Pass_capacity_interpolator.pkl +0 -0
  195. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Droplet_Single_Pass_power_in_interpolator.pkl +0 -0
  196. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Galletti_460_Multi_Pass_bounds.pkl +0 -0
  197. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Galletti_460_Multi_Pass_capacity_interpolator.pkl +0 -0
  198. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Galletti_460_Multi_Pass_power_in_interpolator.pkl +0 -0
  199. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Galletti_778_Multi_Pass_bounds.pkl +0 -0
  200. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Galletti_778_Multi_Pass_capacity_interpolator.pkl +0 -0
  201. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Galletti_778_Multi_Pass_power_in_interpolator.pkl +0 -0
  202. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Laars_eTherm_bounds.pkl +0 -0
  203. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Laars_eTherm_capacity_interpolator.pkl +0 -0
  204. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Laars_eTherm_power_in_interpolator.pkl +0 -0
  205. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Lync_Aegis_500_Single_Pass_bounds.pkl +0 -0
  206. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Lync_Aegis_500_Single_Pass_capacity_interpolator.pkl +0 -0
  207. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Lync_Aegis_500_Single_Pass_power_in_interpolator.pkl +0 -0
  208. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Mitsubishi_QAHV_bounds.pkl +0 -0
  209. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Mitsubishi_QAHV_capacity_interpolator.pkl +0 -0
  210. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Mitsubishi_QAHV_power_in_interpolator.pkl +0 -0
  211. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C125A_bounds.pkl +0 -0
  212. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C125A_capacity_interpolator.pkl +0 -0
  213. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C125A_power_in_interpolator.pkl +0 -0
  214. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C185A_bounds.pkl +0 -0
  215. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C185A_capacity_interpolator.pkl +0 -0
  216. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C185A_power_in_interpolator.pkl +0 -0
  217. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C250A_bounds.pkl +0 -0
  218. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C250A_capacity_interpolator.pkl +0 -0
  219. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C250A_power_in_interpolator.pkl +0 -0
  220. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C25A_bounds.pkl +0 -0
  221. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C25A_capacity_interpolator.pkl +0 -0
  222. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C25A_power_in_interpolator.pkl +0 -0
  223. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C60A_bounds.pkl +0 -0
  224. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C60A_capacity_interpolator.pkl +0 -0
  225. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C60A_power_in_interpolator.pkl +0 -0
  226. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C90A_bounds.pkl +0 -0
  227. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C90A_capacity_interpolator.pkl +0 -0
  228. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_C90A_power_in_interpolator.pkl +0 -0
  229. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_e360_HT_Single_Pass_bounds.pkl +0 -0
  230. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_e360_HT_Single_Pass_capacity_interpolator.pkl +0 -0
  231. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_e360_HT_Single_Pass_power_in_interpolator.pkl +0 -0
  232. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_e360_LT_Single_Pass_bounds.pkl +0 -0
  233. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_e360_LT_Single_Pass_capacity_interpolator.pkl +0 -0
  234. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Nyle_e360_LT_Single_Pass_power_in_interpolator.pkl +0 -0
  235. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_135HNU_483_bounds.pkl +0 -0
  236. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_135HNU_483_capacity_interpolator.pkl +0 -0
  237. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_135HNU_483_power_in_interpolator.pkl +0 -0
  238. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_135VNU_483_bounds.pkl +0 -0
  239. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_135VNU_483_capacity_interpolator.pkl +0 -0
  240. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_135VNU_483_power_in_interpolator.pkl +0 -0
  241. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_60HNU_201_bounds.pkl +0 -0
  242. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_60HNU_201_capacity_interpolator.pkl +0 -0
  243. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_60HNU_201_power_in_interpolator.pkl +0 -0
  244. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_60VNU_201_bounds.pkl +0 -0
  245. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_60VNU_201_capacity_interpolator.pkl +0 -0
  246. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/Rheem_HPHD_60VNU_201_power_in_interpolator.pkl +0 -0
  247. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/SANCO2_GS4_bounds.pkl +0 -0
  248. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/SANCO2_GS4_capacity_interpolator.pkl +0 -0
  249. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/SANCO2_GS4_power_in_interpolator.pkl +0 -0
  250. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/__init__.py +0 -0
  251. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP140_Multi_Pass_bounds.pkl +0 -0
  252. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP140_Multi_Pass_capacity_interpolator.pkl +0 -0
  253. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP140_Multi_Pass_power_in_interpolator.pkl +0 -0
  254. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP140_Single_Pass_bounds.pkl +0 -0
  255. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP140_Single_Pass_capacity_interpolator.pkl +0 -0
  256. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP140_Single_Pass_power_in_interpolator.pkl +0 -0
  257. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP200_Multi_Pass_bounds.pkl +0 -0
  258. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP200_Multi_Pass_capacity_interpolator.pkl +0 -0
  259. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP200_Multi_Pass_power_in_interpolator.pkl +0 -0
  260. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP200_Single_Pass_bounds.pkl +0 -0
  261. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP200_Single_Pass_capacity_interpolator.pkl +0 -0
  262. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP200_Single_Pass_power_in_interpolator.pkl +0 -0
  263. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP280_Multi_Pass_bounds.pkl +0 -0
  264. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP280_Multi_Pass_capacity_interpolator.pkl +0 -0
  265. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP280_Multi_Pass_power_in_interpolator.pkl +0 -0
  266. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP280_Single_Pass_bounds.pkl +0 -0
  267. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP280_Single_Pass_capacity_interpolator.pkl +0 -0
  268. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP280_Single_Pass_power_in_interpolator.pkl +0 -0
  269. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP350_Multi_Pass_bounds.pkl +0 -0
  270. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP350_Multi_Pass_capacity_interpolator.pkl +0 -0
  271. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP350_Multi_Pass_power_in_interpolator.pkl +0 -0
  272. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP350_Single_Pass_bounds.pkl +0 -0
  273. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP350_Single_Pass_capacity_interpolator.pkl +0 -0
  274. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP350_Single_Pass_power_in_interpolator.pkl +0 -0
  275. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP60_Multi_Pass_bounds.pkl +0 -0
  276. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP60_Multi_Pass_capacity_interpolator.pkl +0 -0
  277. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP60_Multi_Pass_power_in_interpolator.pkl +0 -0
  278. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP60_Single_Pass_bounds.pkl +0 -0
  279. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP60_Single_Pass_capacity_interpolator.pkl +0 -0
  280. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lochinvar_AHP60_Single_Pass_power_in_interpolator.pkl +0 -0
  281. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lync_a250_simulated_bounds.pkl +0 -0
  282. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lync_a250_simulated_capacity_interpolator.pkl +0 -0
  283. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lync_a250_simulated_power_in_interpolator.pkl +0 -0
  284. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lync_a350_simulated_bounds.pkl +0 -0
  285. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lync_a350_simulated_capacity_interpolator.pkl +0 -0
  286. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lync_a350_simulated_power_in_interpolator.pkl +0 -0
  287. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lync_a500_simulated_bounds.pkl +0 -0
  288. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lync_a500_simulated_capacity_interpolator.pkl +0 -0
  289. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/data/preformanceMaps/pkls/lync_a500_simulated_power_in_interpolator.pkl +0 -0
  290. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/interfaces/__init__.py +0 -0
  291. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/__init__.py +0 -0
  292. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/building/Building.py +0 -0
  293. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/building/ClimateZone.py +0 -0
  294. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/building/UtilityCostTracker.py +0 -0
  295. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/building/__init__.py +0 -0
  296. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/__init__.py +0 -0
  297. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/heating/Controls.py +0 -0
  298. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/heating/PerformanceMap.py +0 -0
  299. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/heating/WaterHeater.py +0 -0
  300. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/heating/__init__.py +0 -0
  301. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/storage/EnergyTank.py +0 -0
  302. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/storage/MixedStorageTank.py +0 -0
  303. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/storage/SlugOverlayTank.py +0 -0
  304. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/storage/StorageTank.py +0 -0
  305. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/components/storage/__init__.py +0 -0
  306. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/InstantWHSystem.py +0 -0
  307. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/MPNoRecircSystem.py +0 -0
  308. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/__init__.py +0 -0
  309. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/recirc_systems/RecircSystem.py +0 -0
  310. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/recirc_systems/SwingERTrdOffSystem.py +0 -0
  311. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/recirc_systems/__init__.py +0 -0
  312. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/rtp_systems/MP_RTPInSeriesSystem.py +0 -0
  313. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/rtp_systems/SP_RTPInParallelSystem.py +0 -0
  314. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/rtp_systems/SP_RTPInSeriesSystem.py +0 -0
  315. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/dhwsystems/rtp_systems/__init__.py +0 -0
  316. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/objects/simulation/__init__.py +0 -0
  317. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/tests/__init__.py +0 -0
  318. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/tests/test_buildings.py +0 -0
  319. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/tests/test_mixing_valve.py +0 -0
  320. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/tests/test_performance_map.py +0 -0
  321. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine/tests/test_utility_cost_tracker.py +0 -0
  322. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine.egg-info/dependency_links.txt +0 -0
  323. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine.egg-info/requires.txt +0 -0
  324. {ecoengine-3.0.1 → ecoengine-3.0.2}/src/ecoengine.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ecoengine
3
- Version: 3.0.1
3
+ Version: 3.0.2
4
4
  Requires-Python: >=3.11
5
5
  Requires-Dist: numpy
6
6
  Requires-Dist: scipy
@@ -0,0 +1,183 @@
1
+ # EcosizerEngine
2
+
3
+ A Python simulation engine for sizing and simulating domestic hot water (DHW) systems in multi-family and commercial buildings, with a focus on heat pump water heater (HPWH) technology.
4
+
5
+ Requires Python 3.11+. Dependencies: `numpy`, `scipy`, `plotly`.
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ To make the package available to other local apps without publishing it to PyPI, install it in editable mode from the repo root:
12
+
13
+ ```bash
14
+ pip install -e .
15
+ ```
16
+
17
+ Any app that shares the same Python environment can then import from `ecoengine` directly. Changes made to the source files take effect immediately without reinstalling.
18
+
19
+ ---
20
+
21
+ ## What the engine does
22
+
23
+ The engine performs three core functions:
24
+
25
+ 1. **Sizing** — calculates the minimum heating capacity (kBTU/hr) and storage volume (gallons) needed to meet peak daily demand.
26
+ 2. **3-day design-day simulation** — models system performance at 1-minute timesteps over three consecutive peak-demand days.
27
+ 3. **Annual simulation** — full-year simulation at 10-minute timesteps for cost and efficiency analysis.
28
+
29
+ ---
30
+
31
+ ## Package structure
32
+
33
+ ```
34
+ src/ecoengine/
35
+ ├── __init__.py # Re-exports EcosizerEngine and top-level helpers
36
+
37
+ ├── interfaces/
38
+ │ ├── EcosizerEngine.py # Top-level orchestrator and public API
39
+ │ └── Simulator.py # simulate(), simulate_3day(), simulate_annual()
40
+
41
+ ├── objects/
42
+ │ ├── building/
43
+ │ │ ├── Building.py # Occupancy, daily demand, load shapes
44
+ │ │ ├── ClimateZone.py # Hourly OAT and monthly inlet water temps
45
+ │ │ └── UtilityCostTracker.py
46
+ │ │
47
+ │ ├── components/
48
+ │ │ ├── heating/
49
+ │ │ │ ├── WaterHeater.py # Single HPWH unit with on/off state
50
+ │ │ │ ├── PerformanceMap.py # Capacity/power lookup (nominal, pkl, polynomial)
51
+ │ │ │ └── Controls.py # Aquastat setpoints per operating mode
52
+ │ │ └── storage/
53
+ │ │ ├── StorageTank.py # Abstract base class
54
+ │ │ ├── StratifiedTank.py # Continuous linear temperature profile model
55
+ │ │ ├── MixedStorageTank.py # Fully-mixed single-node model (TM tanks)
56
+ │ │ ├── EnergyTank.py # Energy-based base for MPRTP
57
+ │ │ └── SlugOverlayTank.py # Slug overlay for multi-pass RTP simulation
58
+ │ │
59
+ │ ├── dhwsystems/
60
+ │ │ ├── DHWSystem.py # Base class: sizing, simulation step, sizing curve
61
+ │ │ ├── InstantWHSystem.py # Tankless (no storage)
62
+ │ │ ├── MPNoRecircSystem.py # Multi-pass, no recirculation
63
+ │ │ ├── recirc_systems/
64
+ │ │ │ ├── RecircSystem.py # Base for systems with recirc loops
65
+ │ │ │ ├── ParallelLoopSystem.py # Parallel loop with separate TM tank
66
+ │ │ │ ├── SwingSystem.py # Swing tank system
67
+ │ │ │ └── SwingERTrdOffSystem.py # Swing + ER element trade-off variant
68
+ │ │ └── rtp_systems/
69
+ │ │ ├── RTPSystem.py # Base for return-to-primary systems
70
+ │ │ ├── SinglePassRTPSystem.py # SPRTP: recirc returns to primary tank
71
+ │ │ ├── MultiPassRTPSystem.py # MPRTP: growing-slug sizing and simulation
72
+ │ │ ├── SP_RTPInParallelSystem.py
73
+ │ │ ├── SP_RTPInSeriesSystem.py
74
+ │ │ └── MP_RTPInSeriesSystem.py
75
+ │ │
76
+ │ └── simulation/
77
+ │ └── SimulationRun.py # Per-timestep output accumulator and reporting
78
+
79
+ └── data/
80
+ ├── load_shapes/ # 24-hr normalized DHW demand profiles (JSON)
81
+ ├── climate_data/ # CA climate zone weather data (CSV)
82
+ └── preformanceMaps/ # HPWH performance map pkl and JSON files
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Entry point
88
+
89
+ All normal usage goes through `EcosizerEngine`:
90
+
91
+ ```python
92
+ from ecoengine import EcosizerEngine
93
+
94
+ engine = EcosizerEngine(
95
+ building_type = "multi_family",
96
+ num_units = 100,
97
+ zip_code = 94105,
98
+ supply_temp_f = 120,
99
+ storage_temp_f = 150,
100
+ system_type = "parallel_loop",
101
+ )
102
+
103
+ engine.build()
104
+ engine.size()
105
+ results = engine.get_sizing_results()
106
+ ```
107
+
108
+ Top-level helper functions are also importable directly:
109
+
110
+ ```python
111
+ from ecoengine import get_oat_buckets, get_list_of_models, get_weather_stations
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Simulation example
117
+
118
+ The example below sizes a parallel loop system, runs a 3-day design-day simulation, and writes two HTML files: one with the simulation time-series and one with the sizing curve.
119
+
120
+ ```python
121
+ from ecoengine import EcosizerEngine
122
+
123
+ # 1. Configure and size the system.
124
+ # zip_code_or_climate_zone accepts a CA zip code, a zone ID (int),
125
+ # or a dict of design conditions (design_oat_f, design_inlet_water_temp_f).
126
+ engine = EcosizerEngine(
127
+ building_type = "multi_family",
128
+ magnitude = 100, # people
129
+ zip_code_or_climate_zone = 94105, # San Francisco
130
+ supply_temp_f = 120.0,
131
+ storage_temp_f = 150.0,
132
+ schematic = "parallel_loop",
133
+ gpdpp = 25.0, # gallons per person per day
134
+ max_daily_run_hr = 16.0,
135
+ aquastat_fract = 0.4, # ON sensor at 40% tank height
136
+ off_sensor_fract = 0.2, # OFF sensor at 20% tank height
137
+ on_trigger_t_f = 120.0,
138
+ off_trigger_t_f = 140.0,
139
+ return_flow_gpm = 3.0,
140
+ return_temp_f = 110.0,
141
+ tm_on_temp_f = 115.0,
142
+ tm_off_temp_f = 125.0,
143
+ tm_off_time_hr = 0.5,
144
+ )
145
+
146
+ # 2. Check sizing results.
147
+ sizing = engine.get_sizing_results()
148
+ print(f"Capacity: {sizing['min_capacity_kbtuh']:.1f} kBTU/hr")
149
+ print(f"Storage: {sizing['min_storage_storageT_gal']:.0f} gal")
150
+ print(f"TM tank: {sizing['min_tm_volume_gal']:.0f} gal")
151
+
152
+ # 3. Run the 3-day design-day simulation (1-minute timesteps).
153
+ result = engine.simulate_3day()
154
+
155
+ # 4. Plot the simulation time-series and write to an HTML file.
156
+ fig_sim = result.to_plotly(
157
+ title = "3-Day Simulation — 100-Person Multi-Family Parallel Loop",
158
+ include_temperatures = True,
159
+ )
160
+ fig_sim.write_html("simulation.html")
161
+
162
+ # 5. Plot the sizing curve (capacity vs. storage) and write to an HTML file.
163
+ engine.plot_sizing_curve(
164
+ title = "Sizing Curve — 100-Person Multi-Family Parallel Loop",
165
+ filepath = "sizing_curve.html",
166
+ )
167
+
168
+ print("Saved simulation.html and sizing_curve.html")
169
+ ```
170
+
171
+ Open either HTML file in a browser to view the interactive Plotly chart.
172
+
173
+ **Available schematics:** `"parallel_loop"`, `"swing_tank"`, `"single_pass_rtp"`, `"multi_pass_rtp"`, `"no_recirc"`, `"instant"`.
174
+
175
+ For a full working example including load-shift scheduling across multiple system types, see `demo_3day_sim.py` in the repo root.
176
+
177
+ ---
178
+
179
+ ## Running tests
180
+
181
+ ```bash
182
+ pytest src/ecoengine/tests/
183
+ ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ecoengine"
7
- version = "3.0.1"
7
+ version = "3.0.2"
8
8
  requires-python = ">=3.11"
9
9
  dependencies = ["numpy", "scipy", "plotly"]
10
10
 
@@ -878,6 +878,7 @@ class EcosizerEngine:
878
878
  return_flow_gpm = self.return_flow_gpm,
879
879
  max_daily_run_hr = self.max_daily_run_hr,
880
880
  defrost_factor = self.defrost_factor,
881
+ tm_safety_factor = self.tm_safety_factor,
881
882
  control_schedule = control_schedule,
882
883
  control_map = control_map,
883
884
  load_shift_fract_total_vol = ls_fract,
@@ -896,6 +897,7 @@ class EcosizerEngine:
896
897
  return_flow_gpm = self.return_flow_gpm,
897
898
  max_daily_run_hr = 14,
898
899
  defrost_factor = self.defrost_factor,
900
+ tm_safety_factor = self.tm_safety_factor,
899
901
  control_schedule = control_schedule,
900
902
  control_map = control_map,
901
903
  )
@@ -1096,6 +1098,7 @@ class EcosizerEngine:
1096
1098
  return_flow_gpm=self.return_flow_gpm,
1097
1099
  max_daily_run_hr=self.max_daily_run_hr,
1098
1100
  defrost_factor=self.defrost_factor,
1101
+ tm_safety_factor=self.tm_safety_factor,
1099
1102
  )
1100
1103
 
1101
1104
  if self.schematic in ["multi_pass_rtp", "mprtp"]:
@@ -1120,6 +1123,7 @@ class EcosizerEngine:
1120
1123
  return_flow_gpm=self.return_flow_gpm,
1121
1124
  max_daily_run_hr=_MPRTP_MAX_DAILY_RUN_HR,
1122
1125
  defrost_factor=self.defrost_factor,
1126
+ tm_safety_factor=self.tm_safety_factor,
1123
1127
  )
1124
1128
 
1125
1129
  if self.schematic == "instant_wh":
@@ -1345,24 +1349,10 @@ class EcosizerEngine:
1345
1349
  If ``plotly`` is not installed.
1346
1350
  """
1347
1351
  control_schedule, control_map = self._build_control_map()
1348
- fig = self._dhw_system.plot_sizing_curve(
1349
- building = self._building,
1350
- control_schedule = control_schedule,
1351
- control_map = control_map,
1352
- load_shift_percent = self.load_shift_percent,
1353
- strat_slope = strat_slope,
1354
- title = title,
1355
- filepath = filepath,
1356
- )
1357
-
1358
- result = fig.to_html(full_html=False, include_plotlyjs=False) if return_as_div else fig
1359
-
1360
- if not return_with_x_y_points:
1361
- return result
1362
-
1363
1352
  is_ls = "shed" in control_map
1353
+
1364
1354
  if is_ls:
1365
- curve = self._dhw_system.get_ls_sizing_curve(
1355
+ curve = self._dhw_system.get_ls_sizing_curve(
1366
1356
  self._building,
1367
1357
  control_schedule = control_schedule,
1368
1358
  control_map = control_map,
@@ -1378,4 +1368,9 @@ class EcosizerEngine:
1378
1368
  y_vals = curve["capacity_kbtuh"][::-1]
1379
1369
  start_index = len(x_vals) - 1 - curve["recommended_index"]
1380
1370
 
1381
- return [result, x_vals, y_vals, start_index]
1371
+ fig = self._dhw_system._build_sizing_curve_figure(curve, is_ls, title, filepath)
1372
+ result = fig.to_html(full_html=False, include_plotlyjs=False) if return_as_div else fig
1373
+
1374
+ if return_with_x_y_points:
1375
+ return [result, x_vals, y_vals, start_index]
1376
+ return result
@@ -55,7 +55,8 @@ def simulate(dhw_system: DHWSystem, building: Building, duration: str = "3day",
55
55
  sim_run = SimulationRun(duration_min, timestep_min, **sim_run_kwargs)
56
56
 
57
57
  from ecoengine.objects.dhwsystems.recirc_systems.SwingSystem import SwingSystem
58
- sim_run.show_tm_panel = isinstance(dhw_system, SwingSystem)
58
+ from ecoengine.objects.dhwsystems.recirc_systems.SwingERTrdOffSystem import SwingERTrdOffSystem
59
+ sim_run.show_tm_panel = isinstance(dhw_system, SwingSystem) or isinstance(dhw_system, SwingERTrdOffSystem)
59
60
 
60
61
  # Initialize storage tanks
61
62
  inlet_temp_f = building.get_design_inlet_water_temp_f() or 50.0
@@ -99,7 +100,8 @@ def simulate(dhw_system: DHWSystem, building: Building, duration: str = "3day",
99
100
  )
100
101
 
101
102
  if step["usable_volume_supplyT_gal"] <= 0.0:
102
- sim_run.record_outage(timestep_min)
103
+ if not sim_run.show_tm_panel or step.get("tm_tank_temp_f") < dhw_system.supply_temp_f:
104
+ sim_run.record_outage(timestep_min)
103
105
 
104
106
  # Check outlet-deficit stop condition. For systems where the TM/swing
105
107
  # tank is the actual delivery point (e.g. SwingSystem), use its
@@ -37,7 +37,6 @@ class StratifiedTank(StorageTank):
37
37
  def __init__(
38
38
  self,
39
39
  total_volume_gal: float,
40
- num_nodes: int = 12,
41
40
  strat_slope: float = _DEFAULT_STRAT_SLOPE,
42
41
  ) -> None:
43
42
  """
@@ -45,9 +44,6 @@ class StratifiedTank(StorageTank):
45
44
  ----------
46
45
  total_volume_gal : float
47
46
  Total physical tank volume [gallons].
48
- num_nodes : int
49
- Number of vertical temperature nodes (retained for future use;
50
- the analytical profile model does not use discrete nodes).
51
47
  strat_slope : float
52
48
  Temperature gradient through the transition zone between cold and
53
49
  hot layers [°F per percentage-point of tank height]. Higher values
@@ -56,7 +52,6 @@ class StratifiedTank(StorageTank):
56
52
  that model different schematics may set a different value here.
57
53
  """
58
54
  self.total_volume_gal = total_volume_gal
59
- self.num_nodes = num_nodes
60
55
  self.strat_slope = strat_slope
61
56
 
62
57
  # Internal state — set by initialize()
@@ -225,7 +220,7 @@ class StratifiedTank(StorageTank):
225
220
  avg_temp = self.get_average_draw_temp_f(physical_vol)
226
221
  if avg_temp >= outlet_temp_f - 1e-6:
227
222
  self._delta_gal -= physical_vol
228
- self._delta_gal = max(self._delta_gal, self._delta_gal_floor(supply_temp_f))
223
+ self._delta_gal = max(self._delta_gal, self._delta_gal_floor())
229
224
  return
230
225
 
231
226
  # Slow path: draw dips into the transition / cold zone.
@@ -249,7 +244,7 @@ class StratifiedTank(StorageTank):
249
244
  break
250
245
 
251
246
  self._delta_gal -= min((lo + hi) * 0.5, self.total_volume_gal)
252
- self._delta_gal = max(self._delta_gal, self._delta_gal_floor(supply_temp_f))
247
+ self._delta_gal = max(self._delta_gal, self._delta_gal_floor())
253
248
 
254
249
  def heat(
255
250
  self,
@@ -415,7 +410,7 @@ class StratifiedTank(StorageTank):
415
410
  self._inlet_temp_f = inlet_temp_f
416
411
  if gal > 0.0:
417
412
  self._delta_gal -= gal
418
- self._delta_gal = max(self._delta_gal, self._delta_gal_floor(supply_temp_f))
413
+ self._delta_gal = max(self._delta_gal, self._delta_gal_floor())
419
414
 
420
415
  # ------------------------------------------------------------------
421
416
  # Sizing support
@@ -22,6 +22,21 @@ _LS_NORM_STD: float = 0.08236427664525116
22
22
  _LS_NORM_DIST: NormalDist = NormalDist(mu=_LS_NORM_MEAN, sigma=_LS_NORM_STD)
23
23
 
24
24
 
25
+ class StorageVolumeTooSmallError(ValueError):
26
+ """
27
+ Raised when the sized storage volume is below the minimum required floor
28
+ (half the peak-hour demand at supply temperature).
29
+ """
30
+ def __init__(self, storage_storageT_gal: float, minimum_gal: float, capacity_kbtuh: float):
31
+ super().__init__(
32
+ f"Sized storage volume ({storage_storageT_gal:.1f} gal) is less than the "
33
+ f"minimum required volume ({minimum_gal:.1f} gal). "
34
+ "Increase the hours the heat pump runs per day to ensure adequate volume."
35
+ )
36
+ self.storage_storageT_gal = storage_storageT_gal
37
+ self.capacity_kbtuh = capacity_kbtuh
38
+
39
+
25
40
  def _load_shift_fract_total_vol(load_shift_percent: float) -> float:
26
41
  """
27
42
  Convert a load-shift coverage percentile to a demand scaling fraction.
@@ -370,6 +385,10 @@ class DHWSystem:
370
385
  capacity_kbtuh = max(capacity_kbtuh, ls_capacity_kbtuh)
371
386
  storage_vol_storageT_gal = max(storage_vol_storageT_gal, ls_storage_vol_storageT_gal)
372
387
 
388
+ min_vol_gal = self._calc_minimum_running_volume_supplyT_gal(building)
389
+ if storage_vol_storageT_gal < min_vol_gal:
390
+ raise StorageVolumeTooSmallError(storage_vol_storageT_gal, min_vol_gal, capacity_kbtuh)
391
+
373
392
  self._minimum_capacity_kbtuh = capacity_kbtuh
374
393
  self._minimum_storage_storageT_gal = storage_vol_storageT_gal
375
394
  self._sizing_strat_slope = strat_slope
@@ -501,9 +520,12 @@ class DHWSystem:
501
520
  )
502
521
  except (ValueError, RuntimeError):
503
522
  break # aquastat fraction or other sizing failure
504
- heat_hours_out.append(float(h))
505
- capacity_out.append(cap)
506
- storage_out.append(storage_vol)
523
+ if storage_vol < self._calc_minimum_running_volume_supplyT_gal(building):
524
+ break
525
+ else:
526
+ heat_hours_out.append(float(h))
527
+ capacity_out.append(cap)
528
+ storage_out.append(storage_vol)
507
529
  finally:
508
530
  self.max_daily_run_hr = original_run_hr
509
531
 
@@ -704,16 +726,7 @@ class DHWSystem:
704
726
  ImportError
705
727
  If ``plotly`` is not installed.
706
728
  """
707
- try:
708
- import plotly.graph_objects as go
709
- except ImportError:
710
- raise ImportError(
711
- "plotly is required for plot_sizing_curve(). "
712
- "Install it with: pip install plotly"
713
- )
714
-
715
729
  is_ls = self._is_load_shifting(control_map)
716
-
717
730
  if is_ls:
718
731
  curve = self.get_ls_sizing_curve(
719
732
  building,
@@ -722,9 +735,46 @@ class DHWSystem:
722
735
  strat_slope=strat_slope,
723
736
  load_shift_percent=load_shift_percent,
724
737
  )
725
- # X = coverage % (multiply fraction by 100 for readability)
738
+ else:
739
+ curve = self.get_sizing_curve(building, strat_slope=strat_slope)
740
+ return self._build_sizing_curve_figure(curve, is_ls, title, filepath)
741
+
742
+ def _build_sizing_curve_figure(
743
+ self,
744
+ curve: dict,
745
+ is_ls: bool,
746
+ title: str = "Primary Sizing Curve",
747
+ filepath: str | None = None,
748
+ ) -> "plotly.graph_objects.Figure":
749
+ """
750
+ Build and return a Plotly figure from pre-computed sizing curve data.
751
+
752
+ Separating figure assembly from data computation lets callers reuse
753
+ the curve dict (e.g. to extract x/y points) without computing it twice.
754
+
755
+ Parameters
756
+ ----------
757
+ curve : dict
758
+ Output of ``get_sizing_curve()`` or ``get_ls_sizing_curve()``.
759
+ is_ls : bool
760
+ True → load-shift curve layout; False → primary sizing curve layout.
761
+ title : str
762
+ Figure title.
763
+ filepath : str | None
764
+ If provided, write the figure to this path as a self-contained HTML file.
765
+ """
766
+ try:
767
+ import plotly.graph_objects as go
768
+ except ImportError:
769
+ raise ImportError(
770
+ "plotly is required for plot_sizing_curve(). "
771
+ "Install it with: pip install plotly"
772
+ )
773
+
774
+ if is_ls:
726
775
  x_vals = [p * 100.0 for p in curve["load_shift_percent"]]
727
776
  y_vals = curve["storage_storageT_gal"]
777
+ rec = curve["recommended_index"]
728
778
  x_label = "Load-Shift Days Covered (%)"
729
779
  y_label = "Primary Tank Volume (gal at Storage Temperature)"
730
780
  hover = (
@@ -738,13 +788,12 @@ class DHWSystem:
738
788
  f"Storage: <b>{y_vals[i]:.1f} gal</b>"
739
789
  )
740
790
  else:
741
- curve = self.get_sizing_curve(
742
- building,
743
- strat_slope=strat_slope,
744
- )
745
- x_vals = curve["storage_storageT_gal"]
746
- y_vals = curve["capacity_kbtuh"]
747
- heat_hours = curve["heat_hours"]
791
+ # Reverse raw curve (high heat-hours first) so slider moves
792
+ # left-to-right with increasing storage on the x-axis.
793
+ x_vals = curve["storage_storageT_gal"][::-1]
794
+ y_vals = curve["capacity_kbtuh"][::-1]
795
+ heat_hours = curve["heat_hours"][::-1]
796
+ rec = len(x_vals) - 1 - curve["recommended_index"]
748
797
  x_label = "Primary Tank Volume (gal at Storage Temperature)"
749
798
  y_label = "Heating Capacity (kBTU/hr)"
750
799
  hover = (
@@ -752,15 +801,6 @@ class DHWSystem:
752
801
  "Capacity: <b>%{y:.1f} kBTU/hr</b>"
753
802
  "<extra></extra>"
754
803
  )
755
- # The raw curve is ordered high→low storage (high heat hours first).
756
- # Reverse so that the slider moves left-to-right in the same direction
757
- # as the diamond moves along the x-axis (low storage → high storage).
758
- _rec_raw = curve["recommended_index"]
759
- x_vals = x_vals[::-1]
760
- y_vals = y_vals[::-1]
761
- heat_hours = heat_hours[::-1]
762
- rec = len(x_vals) - 1 - _rec_raw
763
-
764
804
  def _slider_label(i: int) -> str:
765
805
  return (
766
806
  f"Storage: <b>{x_vals[i]:.1f} gal</b>, "
@@ -768,8 +808,6 @@ class DHWSystem:
768
808
  f"Run hours: <b>{heat_hours[i]:.2f} hr/day</b>"
769
809
  )
770
810
 
771
- if is_ls:
772
- rec = curve["recommended_index"]
773
811
  fig = go.Figure()
774
812
 
775
813
  # Trace 0: the full sizing curve (always visible)
@@ -789,10 +827,9 @@ class DHWSystem:
789
827
  marker=dict(symbol="diamond", color="#2EA3F2", size=12),
790
828
  hovertemplate=hover,
791
829
  showlegend=False,
792
- visible=(i == rec), # only the recommended point starts visible
830
+ visible=(i == rec),
793
831
  ))
794
832
 
795
- # Build slider steps — each reveals one diamond trace
796
833
  steps = []
797
834
  for i in range(len(x_vals)):
798
835
  visibility = [True] + [j == i for j in range(len(x_vals))]
@@ -947,6 +984,10 @@ class DHWSystem:
947
984
  """
948
985
  return running_volume_supplyT_gal / stratification_factor
949
986
 
987
+ def _calc_minimum_running_volume_supplyT_gal(self, building) -> float:
988
+ """Return the floor running volume: half the peak-hour demand at supply temperature."""
989
+ return float(np.max(building.peak_load_shape)) * building.daily_dhw_use_supplyT_gal / 2.0
990
+
950
991
  def _calc_stratification_factor(
951
992
  self,
952
993
  control_map: dict[str, Controls] | None,
@@ -1681,7 +1722,6 @@ class DHWSystem:
1681
1722
  wh.update_state(self.storage_tank, hour_of_day)
1682
1723
 
1683
1724
  # Apply heating from all active heaters to the tank
1684
- top_temp_f = self.storage_tank.get_temperature_at_fraction(1.0)
1685
1725
  total_kbtuh = sum(
1686
1726
  wh.get_output_kbtuh(oat_f, wh.get_outlet_temp_f(hour_of_day), inlet_temp_f)
1687
1727
  for wh in self.water_heaters
@@ -1696,11 +1736,15 @@ class DHWSystem:
1696
1736
  total_kw = sum(kw or 0.0 for kw in active_kws)
1697
1737
 
1698
1738
  self.storage_tank.heat(total_kbtuh, interval_min, outlet_temp_f)
1739
+ top_temp_f = self.storage_tank.get_temperature_at_fraction(1.0)
1699
1740
 
1700
1741
  # Draw hot water from tank to meet demand
1701
- self.storage_tank.draw(
1702
- demand_supplyT_gal, inlet_temp_f, self.supply_temp_f, outlet_temp_f
1703
- )
1742
+ if top_temp_f >= self.supply_temp_f:
1743
+ self.storage_tank.draw(
1744
+ demand_supplyT_gal, inlet_temp_f, self.supply_temp_f, outlet_temp_f
1745
+ )
1746
+ else:
1747
+ self.storage_tank.draw_physical_gal(demand_supplyT_gal, inlet_temp_f, self.supply_temp_f)
1704
1748
 
1705
1749
  usable_vol_gal = self.storage_tank.get_usable_volume_supplyT_gal(
1706
1750
  self.supply_temp_f
@@ -414,5 +414,4 @@ class ParallelLoopSystem(RecircSystem):
414
414
  step["tm_tank_temp_f"] = self.tm_storage_tank.get_temperature_at_fraction(0.5)
415
415
  step["tm_heater_output_kbtuh"] = tm_kbtuh
416
416
  step["tm_heater_input_kw"] = tm_kw
417
- print(f'{step["tm_heater_input_kw"]}, {step["tm_tank_temp_f"] }, {step["tm_heater_output_kbtuh"]}')
418
417
  return step
@@ -7,7 +7,7 @@ from ecoengine.objects.components.heating.Controls import Controls
7
7
  from ecoengine.objects.components.heating.WaterHeater import WaterHeater
8
8
  from ecoengine.objects.components.storage.StratifiedTank import StratifiedTank
9
9
  from ecoengine.objects.components.storage.MixedStorageTank import MixedStorageTank
10
- from ecoengine.objects.dhwsystems.DHWSystem import _get_peak_indices
10
+ from ecoengine.objects.dhwsystems.DHWSystem import _get_peak_indices, StorageVolumeTooSmallError
11
11
  from .RecircSystem import RecircSystem
12
12
  from ecoengine.constants.constants import _RHO_CP, _W_TO_KBTUH
13
13
 
@@ -260,6 +260,10 @@ class SwingSystem(RecircSystem):
260
260
  storage_vol_storageT_gal = ls_storage_vol
261
261
  self._eff_mix_fraction = ls_eff_mix
262
262
 
263
+ min_vol_gal = self._calc_minimum_running_volume_supplyT_gal(building)
264
+ if storage_vol_storageT_gal < min_vol_gal:
265
+ raise StorageVolumeTooSmallError(storage_vol_storageT_gal, min_vol_gal, capacity_kbtuh)
266
+
263
267
  self._minimum_capacity_kbtuh = capacity_kbtuh
264
268
  self._minimum_storage_storageT_gal = storage_vol_storageT_gal
265
269
  self._sizing_strat_slope = strat_slope
@@ -325,9 +329,12 @@ class SwingSystem(RecircSystem):
325
329
  )
326
330
  except (ValueError, RuntimeError):
327
331
  break
328
- heat_hours_out.append(float(h))
329
- capacity_out.append(cap)
330
- storage_out.append(storage_vol)
332
+ if storage_vol < self._calc_minimum_running_volume_supplyT_gal(building):
333
+ break
334
+ else:
335
+ heat_hours_out.append(float(h))
336
+ capacity_out.append(cap)
337
+ storage_out.append(storage_vol)
331
338
  finally:
332
339
  self.max_daily_run_hr = original_run_hr
333
340