Source code for epconversions.epconversions

# Copyright (c) 2023-2024 Santosh Philip
# =======================================================================
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# =======================================================================

"""Conversion functions for EnergyPlus"""

from typing import Dict
from typing import Optional
from typing import Union
from typing import Any

UnitDictValVal = Optional[Union[str, float, None, list[str]]]
UnitDictVal = Dict[str, UnitDictValVal]
UnitDict = Dict[str, UnitDictVal]

TXT = """! Default IP conversions (no ip-units necessary)
!      $/(m3/s)               =>   $/(ft3/min)         0.000472000059660808
!      $/(W/K)                =>   $/(Btu/h-F)         0.52667614683731
!      $/kW                   =>   $/(kBtuh/h)         0.293083235638921
!      $/m2                   =>   $/ft2               0.0928939733269818
!      $/m3                   =>   $/ft3               0.0283127014102352
!      (kg/s)/W               =>   (lbm/sec)/(Btu/hr)  0.646078115385742
!      1/K                    =>   1/F                 0.555555555555556
!      1/m                    =>   1/ft                0.3048
!      A/K                    =>   A/F                 0.555555555555556
!      C                      =>   F                   1.8 (plus 32)
!      cm                     =>   in                  0.3937
!      cm2                    =>   inch2               0.15500031000062
!      deltaC                 =>   deltaF              1.8
!      deltaC/hr              =>   deltaF/hr           1.8
!      deltaJ/kg              =>   deltaBtu/lb         0.0004299
!      g/GJ                   =>   lb/MWh              0.00793664091373665
!      g/kg                   =>   grains/lb           7
!      g/MJ                   =>   lb/MWh              7.93664091373665
!      g/mol                  =>   lb/mol              0.0022046
!      g/m-s                  =>   lb/ft-s             0.000671968949659
!      g/m-s-K                =>   lb/ft-s-F           0.000373574867724868
!      GJ                     =>   ton-hrs             78.9889415481832
!      J                      =>   Wh                  0.000277777777777778
!      J/K                    =>   Btu/F               526.565
!      J/kg                   =>   Btu/lb              0.00042986
!      J/kg-K                 =>   Btu/lb-F            0.000239005736137667
!      J/kg-K2                =>   Btu/lb-F2           0.000132889924714692
!      J/kg-K3                =>   Btu/lb-F3           7.38277359526066E-05
!      J/m2-K                 =>   Btu/ft2-F           4.89224766847393E-05
!      J/m3                   =>   Btu/ft3             2.68096514745308E-05
!      J/m3-K                 =>   Btu/ft3-F           1.49237004739337E-05
!      K                      =>   R                   1.8
!      K/m                    =>   F/ft                0.54861322767449
!      kg                     =>   lb                  2.2046
!      kg/J                   =>   lb/Btu              2325.83774250441
!      kg/kg-K                =>   lb/lb-F             0.555555555555556
!      kg/m                   =>   lb/ft               0.67196893069637
!      kg/m2                  =>   lb/ft2              0.204794053596664
!      kg/m3                  =>   lb/ft3              0.062428
!      kg/m-s                 =>   lb/ft-s             0.67196893069637
!      kg/m-s-K               =>   lb/ft-s-F           0.373316072609094
!      kg/m-s-K2              =>   lb/ft-s-F2          0.207397818116164
!      kg/Pa-s-m2             =>   lb/psi-s-ft2        1412.00523459398
!      kg/s                   =>   lb/s                2.20462247603796
!      kg/s2                  =>   lb/s2               2.2046
!      kg/s-m                 =>   lb/s-ft             0.67196893069637
!      kJ/kg                  =>   Btu/lb              0.429925
!      kPa                    =>   psi                 0.145038
!      L/day                  =>   pint/day            2.11337629827348
!      L/GJ                   =>   gal/kWh             0.000951022349025202
!      L/kWh                  =>   pint/kWh            2.11337629827348
!      L/MJ                   =>   gal/kWh             0.951022349025202
!      lux                    =>   foot-candles        0.092902267
!      m                      =>   ft                  3.28083989501312
!      m/hr                   =>   ft/hr               3.28083989501312
!      m/s                    =>   ft/min              196.850393700787
!      m/s                    =>   miles/hr            2.2369362920544
!      m/yr                   =>   inch/yr             39.3700787401575
!      m2                     =>   ft2                 10.7639104167097
!      m2/m                   =>   ft2/ft              3.28083989501312
!      m2/person              =>   ft2/person          10.764961
!      m2/s                   =>   ft2/s               10.7639104167097
!      m2-K/W                 =>   ft2-F-hr/Btu        5.678263
!      m3                     =>   ft3                 35.3146667214886
!      m3                     =>   gal                 264.172037284185
!      m3/GJ                  =>   ft3/MWh             127.13292
!      m3/hr                  =>   ft3/hr              35.3146667214886
!      m3/hr-m2               =>   ft3/hr-ft2          3.28083989501312
!      m3/hr-person           =>   ft3/hr-person       35.3146667214886
!      m3/kg                  =>   ft3/lb              16.018
!      m3/m2                  =>   ft3/ft2             3.28083989501312
!      m3/MJ                  =>   ft3/kWh             127.13292
!      m3/person              =>   ft3/person          35.3146667214886
!      m3/s                   =>   ft3/min             2118.88000328931
!      m3/s-m                 =>   ft3/min-ft          645.89
!      m3/s-m2                =>   ft3/min-ft2         196.85
!      m3/s-person            =>   ft3/min-person      2118.6438
!      m3/s-W                 =>   (ft3/min)/(Btu/h)   621.099127332943
!      N-m                    =>   lbf-in              8.85074900525547
!      N-s/m2                 =>   lbf-s/ft2           0.0208857913669065
!      Pa                     =>   psi                 0.000145037743897283
!      percent/K              =>   percent/F           0.555555555555556
!      person/m2              =>   person/ft2          0.0928939733269818
!      s/m                    =>   s/ft                0.3048
!      V/K                    =>   V/F                 0.555555555555556
!      W                      =>   Btu/h               3.4121412858518
!      W/((m3/s)-Pa)          =>   W/((gal/min)-ftH20) 0.188582274697355
!      W/((m3/s)-Pa)          =>   W/((ft3/min)-inH2O) 0.117556910599482
!      W/(m3/s)               =>   W/(ft3/min)         0.0004719475
!      W/K                    =>   Btu/h-F             1.89563404769544
!      W/m                    =>   Btu/h-ft            1.04072
!      W/m2                   =>   Btu/h-ft2           0.316957210776545
!      W/m2                   =>   W/ft2               0.09290304
!      W/m2-K                 =>   Btu/h-ft2-F         0.176110194261872
!      W/m2-K2                =>   Btu/h-ft2-F2        0.097826
!      W/m-K                  =>   Btu-in/h-ft2-F      6.93481276005548
!      W/m-K2                 =>   Btu/h-F2-ft         0.321418310071648
!      W/m-K3                 =>   Btu/h-F3-ft         0.178565727817582
!      W/person               =>   Btu/h-person        3.4121412858518
!
! Other conversions supported (needs the \\ip-units code)
!
!      kPa                    =>   inHg                0.29523
!      m                      =>   in                  39.3700787401575
!      m3/hr                  =>   gal/hr              264.172037284185
!      m3/hr-m2               =>   gal/hr-ft2          24.5423853466941
!      m3/hr-person           =>   gal/hr-person       264.172037284185
!      m3/m2                  =>   gal/ft2             24.5423853466941
!      m3/person              =>   gal/person          264.172037284185
!      m3/s                   =>   gal/min             15850.3222370511
!      m3/s-m                 =>   gal/min-ft          4831.17821785317
!      m3/s-W                 =>   (gal/min)/(Btu/h)   4645.27137336702
!      Pa                     =>   ftH2O               0.00033455
!      Pa                     =>   inH2O               0.00401463
!      Pa                     =>   inHg                0.00029613
!      Pa                     =>   Pa                  1
!      W                      =>   W                   1
!      W/(m3/s)               =>   W/(gal/min)         0.0000630902
!      W/m2                   =>   W/m2                1
!      W/m-K                  =>   Btu/h-ft-F          0.577796066000163
!      W/person               =>   W/person            1
!
! Units fields that are not translated
!      $
!      1/hr
!      A
!      A/V
!      Ah
!      Availability
!      Control
!      cycles/hr
!      days
!      deg
!      dimensionless
!      eV
!      hr
!      J/J
!      kg/kg
!      kg-H2O/kg-air
!      kmol
!      kmol/s
!      m3/m3
!      micron
!      minutes
!      Mode
!      ms
!      ohms
!      percent
!      ppm
!      rev/min
!      s
!      V
!      VA
!      W/m2 or deg C
!      W/m2, W or deg C
!      W/s
!      W/W
!      years
! **************************************************************************
"""


# there are 3 kinds of conversions in the TXT file above
# 1. no ip-units -> use 1st
# 2. expected ip-units -> use second
# 3. use the unit as is if it is in the 3rd category

SI: UnitDict = {
    "$/(m3/s)": {"$/(ft3/min)": 0.000472000059660808},
    "$/(W/K)": {"$/(Btu/h-F)": 0.52667614683731},
    "$/kW": {"$/(kBtuh/h)": 0.293083235638921},
    "$/m2": {"$/ft2": 0.0928939733269818},
    "$/m3": {"$/ft3": 0.0283127014102352},
    "(kg/s)/W": {"(lbm/sec)/(Btu/hr)": 0.646078115385742},
    "1/K": {"1/F": 0.555555555555556},
    "1/m": {"1/ft": 0.3048},
    "A/K": {"A/F": 0.555555555555556},
    "C": {"F": ["1.8", "(plus", "32)"], "C": None},
    "cm": {"in": 0.3937},
    "cm2": {"inch2": 0.15500031000062},
    "deltaC": {"deltaF": 1.8},
    "deltaC/hr": {"deltaF/hr": 1.8},
    "deltaJ/kg": {"deltaBtu/lb": 0.0004299},
    "g/GJ": {"lb/MWh": 0.00793664091373665},
    "g/kg": {"grains/lb": 7.0},
    "g/MJ": {"lb/MWh": 7.93664091373665},
    "g/mol": {"lb/mol": 0.0022046},
    "g/m-s": {"lb/ft-s": 0.000671968949659},
    "g/m-s-K": {"lb/ft-s-F": 0.000373574867724868},
    "GJ": {"ton-hrs": 78.9889415481832},
    "J": {"Wh": 0.000277777777777778},
    "J/K": {"Btu/F": 526.565},
    "J/kg": {"Btu/lb": 0.00042986},
    "J/kg-K": {"Btu/lb-F": 0.000239005736137667},
    "J/kg-K2": {"Btu/lb-F2": 0.000132889924714692},
    "J/kg-K3": {"Btu/lb-F3": 7.38277359526066e-05},
    "J/m2-K": {"Btu/ft2-F": 4.89224766847393e-05},
    "J/m3": {"Btu/ft3": 2.68096514745308e-05},
    "J/m3-K": {"Btu/ft3-F": 1.49237004739337e-05},
    "K": {"R": 1.8},
    "K/m": {"F/ft": 0.54861322767449},
    "kg": {"lb": 2.2046},
    "kg/J": {"lb/Btu": 2325.83774250441},
    "kg/kg-K": {"lb/lb-F": 0.555555555555556},
    "kg/m": {"lb/ft": 0.67196893069637},
    "kg/m2": {"lb/ft2": 0.204794053596664},
    "kg/m3": {"lb/ft3": 0.062428},
    "kg/m-s": {"lb/ft-s": 0.67196893069637},
    "kg/m-s-K": {"lb/ft-s-F": 0.373316072609094},
    "kg/m-s-K2": {"lb/ft-s-F2": 0.207397818116164},
    "kg/Pa-s-m2": {"lb/psi-s-ft2": 1412.00523459398},
    "kg/s": {"lb/s": 2.20462247603796},
    "kg/s2": {"lb/s2": 2.2046},
    "kg/s-m": {"lb/s-ft": 0.67196893069637},
    "kJ/kg": {"Btu/lb": 0.429925},
    "kPa": {"psi": 0.145038, "inHg": 0.29523},
    "L/day": {"pint/day": 2.11337629827348},
    "L/GJ": {"gal/kWh": 0.000951022349025202},
    "L/kWh": {"pint/kWh": 2.11337629827348},
    "L/MJ": {"gal/kWh": 0.951022349025202},
    "lux": {"foot-candles": 0.092902267},
    "m": {"ft": 3.28083989501312, "in": 39.3700787401575},
    "m/hr": {"ft/hr": 3.28083989501312},
    "m/s": {"ft/min": 196.850393700787, "miles/hr": 2.2369362920544},
    "m/yr": {"inch/yr": 39.3700787401575},
    "m2": {"ft2": 10.7639104167097},
    "m2/m": {"ft2/ft": 3.28083989501312},
    "m2/person": {"ft2/person": 10.764961},
    "m2/s": {"ft2/s": 10.7639104167097},
    "m2-K/W": {"ft2-F-hr/Btu": 5.678263},
    "m3": {"ft3": 35.3146667214886, "gal": 264.172037284185},
    "m3/GJ": {"ft3/MWh": 127.13292},
    "m3/hr": {"ft3/hr": 35.3146667214886, "gal/hr": 264.172037284185},
    "m3/hr-m2": {"ft3/hr-ft2": 3.28083989501312, "gal/hr-ft2": 24.5423853466941},
    "m3/hr-person": {
        "ft3/hr-person": 35.3146667214886,
        "gal/hr-person": 264.172037284185,
    },
    "m3/kg": {"ft3/lb": 16.018},
    "m3/m2": {"ft3/ft2": 3.28083989501312, "gal/ft2": 24.5423853466941},
    "m3/MJ": {"ft3/kWh": 127.13292},
    "m3/person": {"ft3/person": 35.3146667214886, "gal/person": 264.172037284185},
    "m3/s": {"ft3/min": 2118.88000328931, "gal/min": 15850.3222370511},
    "m3/s-m": {"ft3/min-ft": 645.89, "gal/min-ft": 4831.17821785317},
    "m3/s-m2": {"ft3/min-ft2": 196.85},
    "m3/s-person": {"ft3/min-person": 2118.6438},
    "m3/s-W": {
        "(ft3/min)/(Btu/h)": 621.099127332943,
        "(gal/min)/(Btu/h)": 4645.27137336702,
    },
    "N-m": {"lbf-in": 8.85074900525547},
    "N-s/m2": {"lbf-s/ft2": 0.0208857913669065},
    "Pa": {
        "psi": 0.000145037743897283,
        "ftH2O": 0.00033455,
        "inH2O": 0.00401463,
        "inHg": 0.00029613,
        "Pa": 1.0,
    },
    "percent/K": {"percent/F": 0.555555555555556},
    "person/m2": {"person/ft2": 0.0928939733269818},
    "s/m": {"s/ft": 0.3048},
    "V/K": {"V/F": 0.555555555555556},
    "W": {"Btu/h": 3.4121412858518, "W": 1.0},
    "W/((m3/s)-Pa)": {
        "W/((gal/min)-ftH20)": 0.188582274697355,
        "W/((ft3/min)-inH2O)": 0.117556910599482,
    },
    "W/(m3/s)": {"W/(ft3/min)": 0.0004719475, "W/(gal/min)": 6.30902e-05},
    "W/K": {"Btu/h-F": 1.89563404769544},
    "W/m": {"Btu/h-ft": 1.04072},
    "W/m2": {"Btu/h-ft2": 0.316957210776545, "W/ft2": 0.09290304, "W/m2": 1.0},
    "W/m2-K": {"Btu/h-ft2-F": 0.176110194261872},
    "W/m2-K2": {"Btu/h-ft2-F2": 0.097826},
    "W/m-K": {"Btu-in/h-ft2-F": 6.93481276005548, "Btu/h-ft-F": 0.577796066000163},
    "W/m-K2": {"Btu/h-F2-ft": 0.321418310071648},
    "W/m-K3": {"Btu/h-F3-ft": 0.178565727817582},
    "W/person": {"Btu/h-person": 3.4121412858518, "W/person": 1.0},
    "$": {"$": None},
    "1/hr": {"1/hr": None},
    "A": {"A": None},
    "A/V": {"A/V": None},
    "Ah": {"Ah": None},
    "Availability": {"Availability": None},
    "Control": {"Control": None},
    "cycles/hr": {"cycles/hr": None},
    "days": {"days": None},
    "deg": {"deg": None},
    "dimensionless": {"dimensionless": None},
    "eV": {"eV": None},
    "hr": {"hr": None},
    "J/J": {"J/J": None},
    "kg/kg": {"kg/kg": None},
    "kg-H2O/kg-air": {"kg-H2O/kg-air": None},
    "kmol": {"kmol": None},
    "kmol/s": {"kmol/s": None},
    "m3/m3": {"m3/m3": None},
    "micron": {"micron": None},
    "minutes": {"minutes": None},
    "Mode": {"Mode": None},
    "ms": {"ms": None},
    "ohms": {"ohms": None},
    "percent": {"percent": None},
    "ppm": {"ppm": None},
    "rev/min": {"rev/min": None},
    "s": {"s": None},
    "V": {"V": None},
    "VA": {"VA": None},
    "W/s": {"W/s": None},
    "W/W": {"W/W": None},
    "years": {"years": None},
}


IP: UnitDict = {
    "$/(ft3/min)": {"$/(m3/s)": 0.000472000059660808},
    "$/(Btu/h-F)": {"$/(W/K)": 0.52667614683731},
    "$/(kBtuh/h)": {"$/kW": 0.293083235638921},
    "$/ft2": {"$/m2": 0.0928939733269818},
    "$/ft3": {"$/m3": 0.0283127014102352},
    "(lbm/sec)/(Btu/hr)": {"(kg/s)/W": 0.646078115385742},
    "1/F": {"1/K": 0.555555555555556},
    "1/ft": {"1/m": 0.3048},
    "A/F": {"A/K": 0.555555555555556},
    "F": {"C": ["1.8", "(plus", "32)"]},
    "in": {"cm": 0.3937, "m": 39.3700787401575},
    "inch2": {"cm2": 0.15500031000062},
    "deltaF": {"deltaC": 1.8},
    "deltaF/hr": {"deltaC/hr": 1.8},
    "deltaBtu/lb": {"deltaJ/kg": 0.0004299},
    "lb/MWh": {"g/GJ": 0.00793664091373665, "g/MJ": 7.93664091373665},
    "grains/lb": {"g/kg": 7.0},
    "lb/mol": {"g/mol": 0.0022046},
    "lb/ft-s": {"g/m-s": 0.000671968949659, "kg/m-s": 0.67196893069637},
    "lb/ft-s-F": {"g/m-s-K": 0.000373574867724868, "kg/m-s-K": 0.373316072609094},
    "ton-hrs": {"GJ": 78.9889415481832},
    "Wh": {"J": 0.000277777777777778},
    "Btu/F": {"J/K": 526.565},
    "Btu/lb": {"J/kg": 0.00042986, "kJ/kg": 0.429925},
    "Btu/lb-F": {"J/kg-K": 0.000239005736137667},
    "Btu/lb-F2": {"J/kg-K2": 0.000132889924714692},
    "Btu/lb-F3": {"J/kg-K3": 7.38277359526066e-05},
    "Btu/ft2-F": {"J/m2-K": 4.89224766847393e-05},
    "Btu/ft3": {"J/m3": 2.68096514745308e-05},
    "Btu/ft3-F": {"J/m3-K": 1.49237004739337e-05},
    "R": {"K": 1.8},
    "F/ft": {"K/m": 0.54861322767449},
    "lb": {"kg": 2.2046},
    "lb/Btu": {"kg/J": 2325.83774250441},
    "lb/lb-F": {"kg/kg-K": 0.555555555555556},
    "lb/ft": {"kg/m": 0.67196893069637},
    "lb/ft2": {"kg/m2": 0.204794053596664},
    "lb/ft3": {"kg/m3": 0.062428},
    "lb/ft-s-F2": {"kg/m-s-K2": 0.207397818116164},
    "lb/psi-s-ft2": {"kg/Pa-s-m2": 1412.00523459398},
    "lb/s": {"kg/s": 2.20462247603796},
    "lb/s2": {"kg/s2": 2.2046},
    "lb/s-ft": {"kg/s-m": 0.67196893069637},
    "psi": {"kPa": 0.145038, "Pa": 0.000145037743897283},
    "pint/day": {"L/day": 2.11337629827348},
    "gal/kWh": {"L/GJ": 0.000951022349025202, "L/MJ": 0.951022349025202},
    "pint/kWh": {"L/kWh": 2.11337629827348},
    "foot-candles": {"lux": 0.092902267},
    "ft": {"m": 3.28083989501312},
    "ft/hr": {"m/hr": 3.28083989501312},
    "ft/min": {"m/s": 196.850393700787},
    "miles/hr": {"m/s": 2.2369362920544},
    "inch/yr": {"m/yr": 39.3700787401575},
    "ft2": {"m2": 10.7639104167097},
    "ft2/ft": {"m2/m": 3.28083989501312},
    "ft2/person": {"m2/person": 10.764961},
    "ft2/s": {"m2/s": 10.7639104167097},
    "ft2-F-hr/Btu": {"m2-K/W": 5.678263},
    "ft3": {"m3": 35.3146667214886},
    "gal": {"m3": 264.172037284185},
    "ft3/MWh": {"m3/GJ": 127.13292},
    "ft3/hr": {"m3/hr": 35.3146667214886},
    "ft3/hr-ft2": {"m3/hr-m2": 3.28083989501312},
    "ft3/hr-person": {"m3/hr-person": 35.3146667214886},
    "ft3/lb": {"m3/kg": 16.018},
    "ft3/ft2": {"m3/m2": 3.28083989501312},
    "ft3/kWh": {"m3/MJ": 127.13292},
    "ft3/person": {"m3/person": 35.3146667214886},
    "ft3/min": {"m3/s": 2118.88000328931},
    "ft3/min-ft": {"m3/s-m": 645.89},
    "ft3/min-ft2": {"m3/s-m2": 196.85},
    "ft3/min-person": {"m3/s-person": 2118.6438},
    "(ft3/min)/(Btu/h)": {"m3/s-W": 621.099127332943},
    "lbf-in": {"N-m": 8.85074900525547},
    "lbf-s/ft2": {"N-s/m2": 0.0208857913669065},
    "percent/F": {"percent/K": 0.555555555555556},
    "person/ft2": {"person/m2": 0.0928939733269818},
    "s/ft": {"s/m": 0.3048},
    "V/F": {"V/K": 0.555555555555556},
    "Btu/h": {"W": 3.4121412858518},
    "W/((gal/min)-ftH20)": {"W/((m3/s)-Pa)": 0.188582274697355},
    "W/((ft3/min)-inH2O)": {"W/((m3/s)-Pa)": 0.117556910599482},
    "W/(ft3/min)": {"W/(m3/s)": 0.0004719475},
    "Btu/h-F": {"W/K": 1.89563404769544},
    "Btu/h-ft": {"W/m": 1.04072},
    "Btu/h-ft2": {"W/m2": 0.316957210776545},
    "W/ft2": {"W/m2": 0.09290304},
    "Btu/h-ft2-F": {"W/m2-K": 0.176110194261872},
    "Btu/h-ft2-F2": {"W/m2-K2": 0.097826},
    "Btu-in/h-ft2-F": {"W/m-K": 6.93481276005548},
    "Btu/h-F2-ft": {"W/m-K2": 0.321418310071648},
    "Btu/h-F3-ft": {"W/m-K3": 0.178565727817582},
    "Btu/h-person": {"W/person": 3.4121412858518},
    "inHg": {"kPa": 0.29523, "Pa": 0.00029613},
    "gal/hr": {"m3/hr": 264.172037284185},
    "gal/hr-ft2": {"m3/hr-m2": 24.5423853466941},
    "gal/hr-person": {"m3/hr-person": 264.172037284185},
    "gal/ft2": {"m3/m2": 24.5423853466941},
    "gal/person": {"m3/person": 264.172037284185},
    "gal/min": {"m3/s": 15850.3222370511},
    "gal/min-ft": {"m3/s-m": 4831.17821785317},
    "(gal/min)/(Btu/h)": {"m3/s-W": 4645.27137336702},
    "ftH2O": {"Pa": 0.00033455},
    "inH2O": {"Pa": 0.00401463},
    "Pa": {"Pa": 1.0},
    "W": {"W": 1.0},
    "W/(gal/min)": {"W/(m3/s)": 6.30902e-05},
    "W/m2": {"W/m2": 1.0},
    "Btu/h-ft-F": {"W/m-K": 0.577796066000163},
    "W/person": {"W/person": 1.0},
    "$": {"$": None},
    "1/hr": {"1/hr": None},
    "A": {"A": None},
    "A/V": {"A/V": None},
    "Ah": {"Ah": None},
    "Availability": {"Availability": None},
    "Control": {"Control": None},
    "cycles/hr": {"cycles/hr": None},
    "days": {"days": None},
    "deg": {"deg": None},
    "dimensionless": {"dimensionless": None},
    "eV": {"eV": None},
    "hr": {"hr": None},
    "J/J": {"J/J": None},
    "kg/kg": {"kg/kg": None},
    "kg-H2O/kg-air": {"kg-H2O/kg-air": None},
    "kmol": {"kmol": None},
    "kmol/s": {"kmol/s": None},
    "m3/m3": {"m3/m3": None},
    "micron": {"micron": None},
    "minutes": {"minutes": None},
    "Mode": {"Mode": None},
    "ms": {"ms": None},
    "ohms": {"ohms": None},
    "percent": {"percent": None},
    "ppm": {"ppm": None},
    "rev/min": {"rev/min": None},
    "s": {"s": None},
    "V": {"V": None},
    "VA": {"VA": None},
    "C": {"C": None},
    "W/s": {"W/s": None},
    "W/W": {"W/W": None},
    "years": {"years": None},
}

SI_DEFAULT: dict[str, str] = {
    "$/(m3/s)": "$/(ft3/min)",
    "$/(W/K)": "$/(Btu/h-F)",
    "$/kW": "$/(kBtuh/h)",
    "$/m2": "$/ft2",
    "$/m3": "$/ft3",
    "(kg/s)/W": "(lbm/sec)/(Btu/hr)",
    "1/K": "1/F",
    "1/m": "1/ft",
    "A/K": "A/F",
    "C": "F",
    "cm": "in",
    "cm2": "inch2",
    "deltaC": "deltaF",
    "deltaC/hr": "deltaF/hr",
    "deltaJ/kg": "deltaBtu/lb",
    "g/GJ": "lb/MWh",
    "g/kg": "grains/lb",
    "g/MJ": "lb/MWh",
    "g/mol": "lb/mol",
    "g/m-s": "lb/ft-s",
    "g/m-s-K": "lb/ft-s-F",
    "GJ": "ton-hrs",
    "J": "Wh",
    "J/K": "Btu/F",
    "J/kg": "Btu/lb",
    "J/kg-K": "Btu/lb-F",
    "J/kg-K2": "Btu/lb-F2",
    "J/kg-K3": "Btu/lb-F3",
    "J/m2-K": "Btu/ft2-F",
    "J/m3": "Btu/ft3",
    "J/m3-K": "Btu/ft3-F",
    "K": "R",
    "K/m": "F/ft",
    "kg": "lb",
    "kg/J": "lb/Btu",
    "kg/kg-K": "lb/lb-F",
    "kg/m": "lb/ft",
    "kg/m2": "lb/ft2",
    "kg/m3": "lb/ft3",
    "kg/m-s": "lb/ft-s",
    "kg/m-s-K": "lb/ft-s-F",
    "kg/m-s-K2": "lb/ft-s-F2",
    "kg/Pa-s-m2": "lb/psi-s-ft2",
    "kg/s": "lb/s",
    "kg/s2": "lb/s2",
    "kg/s-m": "lb/s-ft",
    "kJ/kg": "Btu/lb",
    "kPa": "psi",
    "L/day": "pint/day",
    "L/GJ": "gal/kWh",
    "L/kWh": "pint/kWh",
    "L/MJ": "gal/kWh",
    "lux": "foot-candles",
    "m": "ft",
    "m/hr": "ft/hr",
    "m/s": "ft/min",
    "m/yr": "inch/yr",
    "m2": "ft2",
    "m2/m": "ft2/ft",
    "m2/person": "ft2/person",
    "m2/s": "ft2/s",
    "m2-K/W": "ft2-F-hr/Btu",
    "m3": "ft3",
    "m3/GJ": "ft3/MWh",
    "m3/hr": "ft3/hr",
    "m3/hr-m2": "ft3/hr-ft2",
    "m3/hr-person": "ft3/hr-person",
    "m3/kg": "ft3/lb",
    "m3/m2": "ft3/ft2",
    "m3/MJ": "ft3/kWh",
    "m3/person": "ft3/person",
    "m3/s": "ft3/min",
    "m3/s-m": "ft3/min-ft",
    "m3/s-m2": "ft3/min-ft2",
    "m3/s-person": "ft3/min-person",
    "m3/s-W": "(ft3/min)/(Btu/h)",
    "N-m": "lbf-in",
    "N-s/m2": "lbf-s/ft2",
    "Pa": "psi",
    "percent/K": "percent/F",
    "person/m2": "person/ft2",
    "s/m": "s/ft",
    "V/K": "V/F",
    "W": "Btu/h",
    "W/((m3/s)-Pa)": "W/((gal/min)-ftH20)",
    "W/(m3/s)": "W/(ft3/min)",
    "W/K": "Btu/h-F",
    "W/m": "Btu/h-ft",
    "W/m2": "Btu/h-ft2",
    "W/m2-K": "Btu/h-ft2-F",
    "W/m2-K2": "Btu/h-ft2-F2",
    "W/m-K": "Btu-in/h-ft2-F",
    "W/m-K2": "Btu/h-F2-ft",
    "W/m-K3": "Btu/h-F3-ft",
    "W/person": "Btu/h-person",
    "$": "$",
    "1/hr": "1/hr",
    "A": "A",
    "A/V": "A/V",
    "Ah": "Ah",
    "Availability": "Availability",
    "Control": "Control",
    "cycles/hr": "cycles/hr",
    "days": "days",
    "deg": "deg",
    "dimensionless": "dimensionless",
    "eV": "eV",
    "hr": "hr",
    "J/J": "J/J",
    "kg/kg": "kg/kg",
    "kg-H2O/kg-air": "kg-H2O/kg-air",
    "kmol": "kmol",
    "kmol/s": "kmol/s",
    "m3/m3": "m3/m3",
    "micron": "micron",
    "minutes": "minutes",
    "Mode": "Mode",
    "ms": "ms",
    "ohms": "ohms",
    "percent": "percent",
    "ppm": "ppm",
    "rev/min": "rev/min",
    "s": "s",
    "V": "V",
    "VA": "VA",
    "W/s": "W/s",
    "W/W": "W/W",
    "years": "years",
}

IP_DEFAULT: dict[str, str] = {
    "$/(ft3/min)": "$/(m3/s)",
    "$/(Btu/h-F)": "$/(W/K)",
    "$/(kBtuh/h)": "$/kW",
    "$/ft2": "$/m2",
    "$/ft3": "$/m3",
    "(lbm/sec)/(Btu/hr)": "(kg/s)/W",
    "1/F": "1/K",
    "1/ft": "1/m",
    "A/F": "A/K",
    "F": "C",
    "in": "cm",
    "inch2": "cm2",
    "deltaF": "deltaC",
    "deltaF/hr": "deltaC/hr",
    "deltaBtu/lb": "deltaJ/kg",
    "lb/MWh": "g/GJ",
    "grains/lb": "g/kg",
    "lb/mol": "g/mol",
    "lb/ft-s": "g/m-s",
    "lb/ft-s-F": "g/m-s-K",
    "ton-hrs": "GJ",
    "Wh": "J",
    "Btu/F": "J/K",
    "Btu/lb": "J/kg",
    "Btu/lb-F": "J/kg-K",
    "Btu/lb-F2": "J/kg-K2",
    "Btu/lb-F3": "J/kg-K3",
    "Btu/ft2-F": "J/m2-K",
    "Btu/ft3": "J/m3",
    "Btu/ft3-F": "J/m3-K",
    "R": "K",
    "F/ft": "K/m",
    "lb": "kg",
    "lb/Btu": "kg/J",
    "lb/lb-F": "kg/kg-K",
    "lb/ft": "kg/m",
    "lb/ft2": "kg/m2",
    "lb/ft3": "kg/m3",
    "lb/ft-s-F2": "kg/m-s-K2",
    "lb/psi-s-ft2": "kg/Pa-s-m2",
    "lb/s": "kg/s",
    "lb/s2": "kg/s2",
    "lb/s-ft": "kg/s-m",
    "psi": "kPa",
    "pint/day": "L/day",
    "gal/kWh": "L/GJ",
    "pint/kWh": "L/kWh",
    "foot-candles": "lux",
    "ft": "m",
    "ft/hr": "m/hr",
    "ft/min": "m/s",
    "miles/hr": "m/s",
    "inch/yr": "m/yr",
    "ft2": "m2",
    "ft2/ft": "m2/m",
    "ft2/person": "m2/person",
    "ft2/s": "m2/s",
    "ft2-F-hr/Btu": "m2-K/W",
    "ft3": "m3",
    "gal": "m3",
    "ft3/MWh": "m3/GJ",
    "ft3/hr": "m3/hr",
    "ft3/hr-ft2": "m3/hr-m2",
    "ft3/hr-person": "m3/hr-person",
    "ft3/lb": "m3/kg",
    "ft3/ft2": "m3/m2",
    "ft3/kWh": "m3/MJ",
    "ft3/person": "m3/person",
    "ft3/min": "m3/s",
    "ft3/min-ft": "m3/s-m",
    "ft3/min-ft2": "m3/s-m2",
    "ft3/min-person": "m3/s-person",
    "(ft3/min)/(Btu/h)": "m3/s-W",
    "lbf-in": "N-m",
    "lbf-s/ft2": "N-s/m2",
    "percent/F": "percent/K",
    "person/ft2": "person/m2",
    "s/ft": "s/m",
    "V/F": "V/K",
    "Btu/h": "W",
    "W/((gal/min)-ftH20)": "W/((m3/s)-Pa)",
    "W/((ft3/min)-inH2O)": "W/((m3/s)-Pa)",
    "W/(ft3/min)": "W/(m3/s)",
    "Btu/h-F": "W/K",
    "Btu/h-ft": "W/m",
    "Btu/h-ft2": "W/m2",
    "W/ft2": "W/m2",
    "Btu/h-ft2-F": "W/m2-K",
    "Btu/h-ft2-F2": "W/m2-K2",
    "Btu-in/h-ft2-F": "W/m-K",
    "Btu/h-F2-ft": "W/m-K2",
    "Btu/h-F3-ft": "W/m-K3",
    "Btu/h-person": "W/person",
    "inHg": "kPa",
    "gal/hr": "m3/hr",
    "gal/hr-ft2": "m3/hr-m2",
    "gal/hr-person": "m3/hr-person",
    "gal/ft2": "m3/m2",
    "gal/person": "m3/person",
    "gal/min": "m3/s",
    "gal/min-ft": "m3/s-m",
    "(gal/min)/(Btu/h)": "m3/s-W",
    "ftH2O": "Pa",
    "inH2O": "Pa",
    "Pa": "Pa",
    "W": "W",
    "W/(gal/min)": "W/(m3/s)",
    "W/m2": "W/m2",
    "Btu/h-ft-F": "W/m-K",
    "W/person": "W/person",
    "$": "$",
    "1/hr": "1/hr",
    "A": "A",
    "A/V": "A/V",
    "Ah": "Ah",
    "Availability": "Availability",
    "Control": "Control",
    "cycles/hr": "cycles/hr",
    "days": "days",
    "deg": "deg",
    "dimensionless": "dimensionless",
    "eV": "eV",
    "hr": "hr",
    "J/J": "J/J",
    "kg/kg": "kg/kg",
    "kg-H2O/kg-air": "kg-H2O/kg-air",
    "kmol": "kmol",
    "kmol/s": "kmol/s",
    "m3/m3": "m3/m3",
    "micron": "micron",
    "minutes": "minutes",
    "Mode": "Mode",
    "ms": "ms",
    "ohms": "ohms",
    "percent": "percent",
    "ppm": "ppm",
    "rev/min": "rev/min",
    "s": "s",
    "V": "V",
    "VA": "VA",
    "C": "C",
    "W/s": "W/s",
    "W/W": "W/W",
    "years": "years",
}


[docs] def getconversions( txt: Optional[str] = None, ) -> tuple[UnitDict, UnitDict, Dict[str, str], Dict[str, str]]: """ create the conversion data structure for this library This function generates the values in the constants SI, IP, SI_DEFAULT and IP_DEFAULT. Ulikely that you will ever neeed to use this function. It was used to build up this module :param txt: the raw text from the IDD which contains the conversion factors :returns SI: The value of the SI constant :returns IP: The value of the IP constant :returns SI_DEFAULT: The value of the SI_DEFAULT :returns IP_DEFAULT: The value of the IP_DEFAULT """ if not txt: txt = TXT msp = txt.split("!\n") c1 = msp[0].splitlines() c1.pop(0) si: Dict[str, Any] = dict() ip: Dict[str, Any] = dict() for c in c1: cc = c.split() cc.pop(0) cc.pop(1) try: si.setdefault(cc[0], []).append((cc[1], float(cc[-1]))) ip.setdefault(cc[1], []).append((cc[0], float(cc[-1]))) except ValueError: si.setdefault(cc[0], []).append((cc[1], cc[2:])) ip.setdefault(cc[1], []).append((cc[0], cc[2:])) c1 = msp[2].splitlines() for c in c1: cc = c.split() cc.pop(0) cc.pop(1) try: si.setdefault(cc[0], []).append((cc[1], float(cc[-1]))) ip.setdefault(cc[1], []).append((cc[0], float(cc[-1]))) except ValueError: si.setdefault(cc[0], []).append((cc[1], cc[2:])) ip.setdefault(cc[1], []).append((cc[0], cc[2:])) c2 = msp[3].splitlines() c2.pop(0) c2.pop(-1) for c in [c.split()[-1] for c in c2]: si.setdefault(c, []).append((c, None)) ip.setdefault(c, []).append((c, None)) ssi, iip = _setdefaultindct(si), _setdefaultindct(ip) return ( _remove_defaultkey(ssi), # SI _remove_defaultkey(iip), # IP {k: str(v) for k, v in _getdefaultkey(ssi).items()}, # SI_DEFAULT {k: str(v) for k, v in _getdefaultkey(iip).items()}, # IP_DEFAULT )
def _setdefaultindct(dct: Dict[str, Any]) -> UnitDict: """ Sets a default value to be used internally by 'getconversions` """ newdct = {} for key in dct: d = dict(defaultkey=dct[key][0][0]) d.update(dict(dct[key])) newdct[key] = d return newdct
[docs] def convert2ip( val: float, siunit: str, ipunit: Optional[str] = None, unitstr: bool = True, wrapin: Optional[str] = None, ) -> Union[float, tuple[float, str]]: """ convert val from si units to ip units the conversion will be done to the default ip unit. if you have a specific ip unit you want to convert to, give it's value to the `ipunit` parameter By default, the function will also return the ip unit string. to return only the ip value, set `unitstr=False`. You can wrap the unit string by setting a value to wrapin='[X]' where X is replaced by the unit string. '[' and ']' can be any string Sample code:: epconversions.convert2ip(4, 'm') >> (13.12335958005248, 'ft') epconversions.convert2ip(4, 'm', 'in') >> (157.48031496063, 'in') epconversions.convert2ip(4, 'm', 'in', unitstr=None) >> 157.48031496063 epconversions.convert2ip(4, 'm', 'in', wrapin='[X]') >> (157.48031496063, '[in]') epconversions.convert2ip(4, 'm', 'in', wrapin='unit = [X]') >> (157.48031496063, 'unit = [in]') :param val: a numeric value :param siunit: the unit for the value (kg, m, etc.) :param ipunit: if you know the ip unit you want returned. Else it will use the default unit :param unitstr: True if you want the unit string returned :param wrapin: wrap the init string in this. :returns new_val: The new converted value :returns ustr: returns unit string if unitstr=True """ # calculates the new value # get conversion factor conv: Optional[Union[str, float, None, list[str]]] if not siunit: conv = 1.0 elif siunit not in SI: conv = 1.0 elif not ipunit: default = SI_DEFAULT[siunit] conv = SI[siunit][default] else: conv = SI[siunit][ipunit] # do conversion new_val = _doconversion(val, conv) # make the unit string ustr = "" if unitstr: if not siunit: ustr = "" elif siunit not in SI: ustr = siunit elif ipunit: ustr = ipunit else: ustr = default # wrap the unitstr if not wrapin: wrapin = "X" elif ustr: ustr = wrapin.replace("X", ustr) else: pass # return the results if unitstr: return new_val, ustr else: return new_val
[docs] def convert2si( val: float, ipunit: str, siunit: Optional[str] = None, unitstr: bool = True, wrapin: Optional[str] = None, ) -> Union[float, tuple[float, str]]: """ convert val from ip units to si units the conversion will be done to the default si unit. if you have a specific si unit you want to convert to, give it's value to the `siunit` parameter By default, the function will also return the si unit string. to return only the si value, set `unitstr=False`. You can wrap the unit string by setting a value to wrapin='[X]' where X is replaced by the unit string. '[' and ']' can be any string Sample code:: epconversions.convert2si(5, 'in') >> (12.700025400050801, 'cm') epconversions.convert2si(5, 'in', 'm') >> (0.12699999999999992, 'm') epconversions.convert2si(5, 'in', 'm', unitstr=False) >> 0.12699999999999992 epconversions.convert2si(5, 'in', 'm', wrapin='[X]') >> (0.12699999999999992, '[m]') epconversions.convert2si(5, 'in', 'm', wrapin='unit = [X]') >> wrapin='unit = [X]') :param val: a numeric value :param ipunit: the unit for the value (ft, in, F etc.) :param siunit: if you know the si unit you want returned. Else it will use the default unit :param unitstr: True if you want the unit string returned :param wrapin: wrap the init string in this. :returns new_val: The new converted value :returns ustr: returns unit string if unitstr=True """ # calculates the new value # get conversion factor # conv: Optional[Union[str, float, None, list[str]]] conv: UnitDictValVal if not ipunit: conv = 1.0 elif ipunit not in IP: conv = 1.0 elif not siunit: default = IP_DEFAULT[ipunit] conv = IP[ipunit][default] else: conv = IP[ipunit][siunit] # do conversion new_val = _doconversion(val, conv, reverse=True) # make the unit string ustr = "" if unitstr: if not ipunit: ustr = "" elif ipunit not in IP: ustr = ipunit elif siunit: ustr = siunit else: ustr = default # wrap the unitstr if not wrapin: wrapin = "X" elif ustr: ustr = wrapin.replace("X", ustr) else: pass # return the results if unitstr: return new_val, ustr else: return new_val
def _doconversion( val: float, conv: Optional[Union[str, float, None, list[str]]], reverse: bool = False, ) -> float: """does the conversions :param val: val is converted :param conv: this is the conversion factor or rule :param reverse: if True, use 1/conv or reverse of the rule :returns new_value: the converted value """ try: val = float(val) except (ValueError, TypeError) as e: pass if reverse: try: conv = 1 / conv # type: ignore except TypeError: pass try: if conv == ["1.8", "(plus", "32)"]: if reverse: new_val = (val - 32) / 1.8 else: new_val = (val * 1.8) + 32 else: new_val = val * conv # type: ignore except TypeError: new_val = val return new_val
[docs] def allsiunits() -> list[str]: """return a list of all SI units that this module can convert :returns siunits: a list of all si units """ return list(SI.keys())
[docs] def allipunits() -> list[str]: """return a list of all the IP units that this module can convert :returns ipunits: a list of all ip units """ return list(IP.keys())
[docs] def getipunits(siunit: str, si: Optional[UnitDict] = None) -> set[str]: """return all the ip units avaliable for this si unit :param siunit: si unit :param si: Use this in case you want to override the default constant SI :returns ipunits: all the ip units avaliable for this si unit """ if not si: si = SI dct = dict(si[siunit]) return set(dct.keys())
[docs] def getsiunits(ipunit: str, ip: Optional[UnitDict] = None) -> set[str]: """return all the si units avaliable for this ip unit :param ipunit: ip unit :param ip: Use this in case you want to override the default constant IP :returns siunts: all the si units avaliable for this ip unit """ if not ip: ip = IP dct = dict(ip[ipunit]) return set(dct.keys())
def _remove_defaultkey(a: UnitDict) -> UnitDict: """for internal use""" return {k: {kk: a[k][kk] for kk in a[k] if kk != "defaultkey"} for k in a} def _getdefaultkey(a: UnitDict) -> UnitDictVal: """for internal use by getconversions""" return {k: a[k]["defaultkey"] for k in a}
[docs] def defaultsiunit(ipunit: str) -> str: """get the default `si unit` for the given `ip unit` :param ipunit: ip unit :returns siunit: the default `si unit` for the given `ip unit` """ return IP_DEFAULT[ipunit]
[docs] def defaultipunit(siunit: str) -> str: """get the default `ip unit` for the given `si unit` :param siunit: si unit :returns ipunit: the default `ip unit` for the given `si unit` """ return SI_DEFAULT[siunit]