Reader for TMY3 weather data

within AixLib.BoundaryConditions.WeatherData;
block ReaderTMY3 "Reader for TMY3 weather data"

  Bus weaBus "Weather data bus"

  //--------------------------------------------------------------
  parameter String filNam="" "Name of weather data file"

  parameter Boolean computeWetBulbTemperature = true
    "If true, then this model computes the wet bulb temperature"

  //--------------------------------------------------------------
  // Atmospheric pressure
  parameter AixLib.BoundaryConditions.Types.DataSource pAtmSou=AixLib.BoundaryConditions.Types.DataSource.Parameter
    "Atmospheric pressure"
  parameter Modelica.Units.SI.Pressure pAtm=101325
    "Atmospheric pressure (used if pAtmSou=Parameter)"
  Modelica.Blocks.Interfaces.RealInput pAtm_in(
    final quantity="Pressure",
    final unit="Pa",
    displayUnit="Pa") if (pAtmSou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Input pressure"

  //--------------------------------------------------------------
  // Dry bulb temperature
  parameter AixLib.BoundaryConditions.Types.DataSource TDryBulSou=AixLib.BoundaryConditions.Types.DataSource.File
    "Dry bulb temperature"
  parameter Modelica.Units.SI.Temperature TDryBul(displayUnit="degC") = 293.15
    "Dry bulb temperature (used if TDryBul=Parameter)"
  Modelica.Blocks.Interfaces.RealInput TDryBul_in(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") if (TDryBulSou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Input dry bulb temperature"

  //--------------------------------------------------------------
  // Dew point temperature
  parameter AixLib.BoundaryConditions.Types.DataSource TDewPoiSou=AixLib.BoundaryConditions.Types.DataSource.File
    "Dew point temperature"
  parameter Modelica.Units.SI.Temperature TDewPoi(displayUnit="degC") = 283.15
    "Dew point temperature (used if TDewPoi=Parameter)"
  Modelica.Blocks.Interfaces.RealInput TDewPoi_in(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") if (TDewPoiSou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Input dew point temperature"

  //--------------------------------------------------------------
  // Black body sky temperature
  parameter AixLib.BoundaryConditions.Types.DataSource TBlaSkySou=AixLib.BoundaryConditions.Types.DataSource.File
    "Black-body sky temperature"
  parameter Modelica.Units.SI.Temperature TBlaSky=273.15
    "Black-body sky temperature (used if TBlaSkySou=Parameter)"
  Modelica.Blocks.Interfaces.RealInput TBlaSky_in(
    final quantity="ThermodynamicTemperature",
    displayUnit="degC",
    final unit="K")
 if (TBlaSkySou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Black-body sky temperature"
  //--------------------------------------------------------------
  // Relative humidity
  parameter AixLib.BoundaryConditions.Types.DataSource relHumSou=AixLib.BoundaryConditions.Types.DataSource.File
    "Relative humidity"
  parameter Real relHum(
    min=0,
    max=1,
    unit="1") = 0.5 "Relative humidity (used if relHum=Parameter)"
  Modelica.Blocks.Interfaces.RealInput relHum_in(
    min=0,
    max=1,
    unit="1") if (relHumSou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Input relative humidity"
  //--------------------------------------------------------------
  // Wind speed
  parameter AixLib.BoundaryConditions.Types.DataSource winSpeSou=AixLib.BoundaryConditions.Types.DataSource.File
    "Wind speed"
  parameter Modelica.Units.SI.Velocity winSpe(min=0) = 1
    "Wind speed (used if winSpe=Parameter)"
  Modelica.Blocks.Interfaces.RealInput winSpe_in(
    final quantity="Velocity",
    final unit="m/s",
    min=0) if (winSpeSou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Input wind speed"
  //--------------------------------------------------------------
  // Wind direction
  parameter AixLib.BoundaryConditions.Types.DataSource winDirSou=AixLib.BoundaryConditions.Types.DataSource.File
    "Wind direction"
  parameter Modelica.Units.SI.Angle winDir=1.0
    "Wind direction (used if winDir=Parameter)"
  Modelica.Blocks.Interfaces.RealInput winDir_in(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") if (winDirSou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Input wind direction"
  //--------------------------------------------------------------
  // Infrared horizontal radiation
  parameter AixLib.BoundaryConditions.Types.DataSource HInfHorSou=AixLib.BoundaryConditions.Types.DataSource.File
    "Infrared horizontal radiation"
  parameter Modelica.Units.SI.HeatFlux HInfHor=0.0
    "Infrared horizontal radiation (used if HInfHorSou=Parameter)"
  Modelica.Blocks.Interfaces.RealInput HInfHor_in(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2") if (HInfHorSou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Input infrared horizontal radiation"

   parameter AixLib.BoundaryConditions.Types.RadiationDataSource HSou=AixLib.BoundaryConditions.Types.RadiationDataSource.File
    "Global, diffuse, and direct normal radiation"
  //--------------------------------------------------------------
  // Global horizontal radiation
  Modelica.Blocks.Interfaces.RealInput HGloHor_in(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
      if (HSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HGloHor_HDifHor or
          HSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HDirNor_HGloHor)
    "Input global horizontal radiation"
  //--------------------------------------------------------------
  // Diffuse horizontal radiation
  Modelica.Blocks.Interfaces.RealInput HDifHor_in(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
      if (HSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HGloHor_HDifHor or
          HSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HDirNor_HDifHor)
    "Input diffuse horizontal radiation"
  //--------------------------------------------------------------
  // Direct normal radiation
  Modelica.Blocks.Interfaces.RealInput HDirNor_in(final quantity="RadiantEnergyFluenceRate",
      final unit="W/m2")
      if (HSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HDirNor_HDifHor or
          HSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HDirNor_HGloHor)
    "Input direct normal radiation"

//--------------------------------------------------------------
  // Ceiling height
  parameter AixLib.BoundaryConditions.Types.DataSource ceiHeiSou=AixLib.BoundaryConditions.Types.DataSource.File
    "Ceiling height"
  parameter Real ceiHei(
    final quantity="Height",
    final unit="m",
    displayUnit="m") = 20000 "Ceiling height (used if ceiHei=Parameter)"
  Modelica.Blocks.Interfaces.RealInput ceiHei_in(
    final quantity="Height",
    final unit="m",
    displayUnit="m") if (ceiHeiSou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Input ceiling height"
  //--------------------------------------------------------------
  // Total sky cover
  parameter AixLib.BoundaryConditions.Types.DataSource totSkyCovSou=AixLib.BoundaryConditions.Types.DataSource.File
    "Total sky cover"
  parameter Real totSkyCov(
    min=0,
    max=1,
    unit="1") = 0.5
    "Total sky cover (used if totSkyCov=Parameter). Use 0 <= totSkyCov <= 1"
  Modelica.Blocks.Interfaces.RealInput totSkyCov_in(
    min=0,
    max=1,
    unit="1") if (totSkyCovSou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Input total sky cover"
  // Opaque sky cover
  parameter AixLib.BoundaryConditions.Types.DataSource opaSkyCovSou=AixLib.BoundaryConditions.Types.DataSource.File
    "Opaque sky cover"
  parameter Real opaSkyCov(
    min=0,
    max=1,
    unit="1") = 0.5
    "Opaque sky cover (used if opaSkyCov=Parameter). Use 0 <= opaSkyCov <= 1"
  Modelica.Blocks.Interfaces.RealInput opaSkyCov_in(
    min=0,
    max=1,
    unit="1") if (opaSkyCovSou == AixLib.BoundaryConditions.Types.DataSource.Input)
    "Input opaque sky cover"

  parameter AixLib.BoundaryConditions.Types.SkyTemperatureCalculation
    calTSky=AixLib.BoundaryConditions.Types.SkyTemperatureCalculation.TemperaturesAndSkyCover
    "Model choice for black-body sky temperature calculation"

  final parameter Modelica.Units.SI.Angle lon(displayUnit="deg") =
    AixLib.BoundaryConditions.WeatherData.BaseClasses.getLongitudeTMY3(filNam)
    "Longitude";
  final parameter Modelica.Units.SI.Angle lat(displayUnit="deg") =
    AixLib.BoundaryConditions.WeatherData.BaseClasses.getLatitudeTMY3(filNam)
    "Latitude";
  final parameter Modelica.Units.SI.Time timZon(displayUnit="h") =
    AixLib.BoundaryConditions.WeatherData.BaseClasses.getTimeZoneTMY3(filNam)
    "Time zone";
  final parameter Modelica.Units.SI.Length alt(displayUnit="m") =
    AixLib.BoundaryConditions.WeatherData.BaseClasses.getAltitudeLocationTMY3(
    filNam) "Location altitude above sea level";

protected
  final parameter Modelica.Units.SI.Time[2] timeSpan=
      AixLib.BoundaryConditions.WeatherData.BaseClasses.getTimeSpanTMY3(filNam,
      "tab1") "Start time, end time of weather data";

  Modelica.Blocks.Tables.CombiTable1Ds datRea(
    final tableOnFile=true,
    final tableName="tab1",
    final fileName=filNam,
    verboseRead=false,
    final smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative,
    final columns={2,3,4,5,6,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,
        28,29,30,8}) "Data reader"

  BaseClasses.SourceSelector pAtmSel(
    final datSou=pAtmSou,
    final p=pAtm) "Source selection for atmospheric pressure"
  BaseClasses.SourceSelector TDewPoiSel(
    final datSou=TDewPoiSou,
    final p=TDewPoi)
    "Source selection for dewpoint temperature pressure"
  BaseClasses.SourceSelector TDryBulSel(
    final datSou=TDryBulSou,
    final p=TDryBul)
    "Source selection for drybulb temperature pressure"
  BaseClasses.SourceSelector TBlaSkySel(
    final datSou=TBlaSkySou,
    final p=TBlaSky)
    "Source selection for sky black body radiation"
  BaseClasses.SourceSelector relHumSel(
    final datSou=relHumSou,
    final p=relHum)
    "Source selection for relative humidity"
  BaseClasses.SourceSelector opaSkyCovSel(
    final datSou=opaSkyCovSou,
    final p=opaSkyCov)
    "Source selection for opaque sky cover"
  BaseClasses.SourceSelector ceiHeiSel(
    final datSou=ceiHeiSou,
    final p=ceiHei)
    "Source selection for ceiling height"
  BaseClasses.SourceSelector totSkyCovSel(
    final datSou=totSkyCovSou,
    final p=totSkyCov)
    "Source selection for total sky cover"
  BaseClasses.SourceSelector winSpeSel(
    final datSou=winSpeSou,
    final p=winSpe)
    "Source selection for wind speed"
  BaseClasses.SourceSelector winDirSel(
    final datSou=winDirSou,
    final p=winDir)
    "Source selection for wind speed"
  BaseClasses.SourceSelector horInfRadSel(
    final datSou=HInfHorSou,
    final p=HInfHor)
    "Source selection for horizontal infrared radiation"
  BaseClasses.SourceSelectorRadiation souSelRad(
    final datSou=HSou)
    "Source selection for solar irradiation"

  BaseClasses.CheckDryBulbTemperature
    cheTemDryBul "Check dry bulb temperature "
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckDewPointTemperature
    cheTemDewPoi "Check dew point temperature"
  Modelica.Blocks.Math.Gain conRelHum(final k=0.01)
    if relHumSou == AixLib.BoundaryConditions.Types.DataSource.File
    "Convert the relative humidity from percentage to [0, 1] "
  BaseClasses.CheckPressure chePre "Check the air pressure"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LimiterRelativeHumidity limRelHum
    "Limiter for relative humidity"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LimiterTotalSkyCover limTotSkyCov
    "Limits the total sky cover"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LimiterOpaqueSkyCover limOpaSkyCov
    "Limits the opaque sky cover"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LimiterCeilingHeight limCeiHei "Limits the ceiling height"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LimiterWindSpeed limWinSpe "Limits the wind speed"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LimiterHorizontalInfraredIrradiation limHorInfRad
    "Limits the horizontal infrared irradiation"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LimiterWindDirection limWinDir
    "Limits the wind direction"
  SkyTemperature.BlackBody TBlaSkyCom(final calTSky=calTSky)
    if TBlaSkySou == AixLib.BoundaryConditions.Types.DataSource.File
    "Computation of the black-body sky temperature"
  AixLib.Utilities.Time.ModelTime modTim "Model time"
  Modelica.Blocks.Math.Add add30Min
    "Add 30 minutes to time to shift weather data reader"
  Modelica.Blocks.Sources.Constant con30Min(final k=1800)
    "Constant used to shift weather data reader"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LocalCivilTime locTim(
      final lon=lon, final timZon=timZon) "Local civil time"
  Modelica.Blocks.Tables.CombiTable1Ds datRea30Min(
    final tableOnFile=true,
    final tableName="tab1",
    final fileName=filNam,
    verboseRead=false,
    final smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative,
    final columns=9:11) "Data reader with 30 min offset for solar irradiation"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTimMin(final
      weaDatStaTim=timeSpan[1], final weaDatEndTim=timeSpan[2])
    "Convert simulation time to calendar time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTim(
    final weaDatStaTim = timeSpan[1],
    final weaDatEndTim = timeSpan[2])
    "Convert simulation time to calendar time"
  BaseClasses.EquationOfTime eqnTim "Equation of time"
  BaseClasses.SolarTime solTim "Solar time"

  Modelica.Blocks.Math.UnitConversions.From_deg conWinDir
    "Convert the wind direction unit from [deg] to [rad]"
  Modelica.Blocks.Math.UnitConversions.From_degC conTDryBul

  Modelica.Blocks.Math.UnitConversions.From_degC conTDewPoi
    "Convert the dew point temperature form [degC] to [K]"
  SolarGeometry.BaseClasses.AltitudeAngle altAng "Solar altitude angle"
   SolarGeometry.BaseClasses.ZenithAngle zenAng
                      "Zenith angle"
   SolarGeometry.BaseClasses.Declination decAng "Declination angle"
   SolarGeometry.BaseClasses.SolarHourAngle
    solHouAng "Solar hour angle"
  Latitude latitude(final latitude=lat) "Latitude"
  Longitude longitude(final longitude=lon) "Longitude"
  Altitude altitude(final Altitude=alt) "Altitude"
  //---------------------------------------------------------------------------
  // Optional instanciation of a block that computes the wet bulb temperature.
  // This block may be needed for evaporative cooling towers.
  // By default, it is enabled. This introduces a nonlinear equation, but
  // we have not observed an increase in computing time because of this equation.
  AixLib.Utilities.Psychrometrics.TWetBul_TDryBulPhi tWetBul_TDryBulXi(
      redeclare package Medium = AixLib.Media.Air,
      TDryBul(displayUnit="degC")) if computeWetBulbTemperature

  //---------------------------------------------------------------------------
  // Conversion blocks for sky cover
  Modelica.Blocks.Math.Gain conTotSkyCov(final k=0.1)
    if totSkyCovSou == AixLib.BoundaryConditions.Types.DataSource.File
    "Convert sky cover from [0...10] to [0...1]"
  Modelica.Blocks.Math.Gain conOpaSkyCov(final k=0.1)
    if opaSkyCovSou == AixLib.BoundaryConditions.Types.DataSource.File
    "Convert sky cover from [0...10] to [0...1]"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckBlackBodySkyTemperature cheTemBlaSky(TMin=0)
    "Check black body sky temperature"

  // Blocks that are added in order to set the name of the output signal,
  // which then is displayed in the GUI of the weather data connector.
  block Latitude "Generate constant signal of type Real"
    extends Modelica.Blocks.Icons.Block;

    parameter Modelica.Units.SI.Angle latitude "Latitude";

    Modelica.Blocks.Interfaces.RealOutput y(
      unit="rad",
      displayUnit="deg") "Latitude of the location"
  equation
    y = latitude;
  end Latitude;

  block Longitude "Generate constant signal of type Real"
    extends Modelica.Blocks.Icons.Block;

    parameter Modelica.Units.SI.Angle longitude "Longitude";

    Modelica.Blocks.Interfaces.RealOutput y(
      unit="rad",
      displayUnit="deg") "Longitude of the location"
  equation
    y = longitude;
  end Longitude;

  block Altitude "Generate constant signal of type Real"
    extends Modelica.Blocks.Icons.Block;

    parameter Modelica.Units.SI.Length Altitude
      "Location altitude above sea level";

    Modelica.Blocks.Interfaces.RealOutput y(
      unit="m") "Location altitude above sea level"
  equation
    y = Altitude;
  end Altitude;

equation

  connect(modTim.y, add30Min.u2)
  connect(con30Min.y, add30Min.u1)
  connect(add30Min.y, conTimMin.modTim)
  connect(conTimMin.calTim, datRea30Min.u)
  connect(modTim.y, locTim.cloTim)
  connect(modTim.y, conTim.modTim)
  connect(conTim.calTim, datRea.u)
  connect(modTim.y, eqnTim.nDay)
  connect(eqnTim.eqnTim, solTim.equTim)
  connect(locTim.locTim, solTim.locTim)
  connect(datRea.y[11], conWinDir.u)
  connect(datRea.y[1], conTDryBul.u)
  connect(datRea.y[2], conTDewPoi.u)
  connect(conRelHum.u, datRea.y[3])

  connect(decAng.decAng, zenAng.decAng)
  connect(solHouAng.solHouAng, zenAng.solHouAng)
  connect(solHouAng.solTim, solTim.solTim)
  connect(decAng.nDay, modTim.y)
  connect(zenAng.zen, altAng.zen)

  connect(limOpaSkyCov.nOpa, TBlaSkyCom.nOpa)
  connect(limRelHum.relHum, tWetBul_TDryBulXi.phi)

  connect(pAtmSel.y, chePre.PIn)
  connect(pAtmSel.uCon, pAtm_in)
  connect(datRea.y[4], pAtmSel.uFil)
  connect(cheTemDewPoi.TIn, TDewPoiSel.y)
  connect(TDewPoiSel.uFil, conTDewPoi.y)
  connect(TDewPoiSel.uCon, TDewPoi_in)
  connect(TDryBulSel.y, cheTemDryBul.TIn)
  connect(TDryBulSel.uFil, conTDryBul.y)
  connect(TDryBulSel.uCon, TDryBul_in)

  connect(TBlaSkySel.y, cheTemBlaSky.TIn)
  connect(TBlaSkyCom.TBlaSky, TBlaSkySel.uFil)
  connect(TBlaSky_in, TBlaSkySel.uCon)
  connect(relHumSel.y, limRelHum.u)
  connect(relHumSel.uFil, conRelHum.y)
  connect(relHum_in, relHumSel.uCon)
  connect(conOpaSkyCov.y, opaSkyCovSel.uFil)
  connect(opaSkyCov_in, opaSkyCovSel.uCon)
  connect(ceiHeiSel.y, limCeiHei.u)
  connect(ceiHeiSel.uFil, datRea.y[16])
  connect(ceiHeiSel.uCon, ceiHei_in)
  connect(totSkyCovSel.uFil, conTotSkyCov.y)
  connect(totSkyCovSel.uCon, totSkyCov_in)
  connect(totSkyCovSel.y, limTotSkyCov.u)
  connect(winSpeSel.y, limWinSpe.u)
  connect(conTotSkyCov.u, datRea.y[13])
  connect(winSpeSel.uFil, datRea.y[12])
  connect(winSpeSel.uCon, winSpe_in)
  connect(winDirSel.y, limWinDir.u)
  connect(conWinDir.y, winDirSel.uFil)
  connect(winDirSel.uCon, winDir_in)
  connect(conOpaSkyCov.u, datRea.y[14])
  connect(horInfRadSel.y, limHorInfRad.u)
  connect(horInfRadSel.uFil, datRea.y[26])
  connect(horInfRadSel.uCon, HInfHor_in)

  connect(souSelRad.HDifHorFil, datRea30Min.y[3])
  connect(souSelRad.HDifHorIn, HDifHor_in)
  connect(souSelRad.HDirNorFil, datRea30Min.y[2])
  connect(souSelRad.HDirNorIn, HDirNor_in)
  connect(souSelRad.HGloHorIn, HGloHor_in)
  connect(souSelRad.zen, zenAng.zen)
  connect(souSelRad.HGloHorFil, datRea30Min.y[1])

  connect(TBlaSkyCom.HHorIR, limHorInfRad.HHorIR)

  connect(opaSkyCovSel.y, limOpaSkyCov.u)
  connect(cheTemDryBul.TDryBul, TBlaSkyCom.TDryBul)
  connect(cheTemDryBul.TDryBul, tWetBul_TDryBulXi.TDryBul)

  connect(chePre.pAtm, tWetBul_TDryBulXi.p)

  connect(cheTemDewPoi.TDewPoi, TBlaSkyCom.TDewPoi)

  // Connections to weather data bus
  connect(cheTemDryBul.TDryBul, weaBus.TDryBul)

  connect(cheTemDewPoi.TDewPoi, weaBus.TDewPoi)
  connect(tWetBul_TDryBulXi.TWetBul, weaBus.TWetBul)

  connect(limRelHum.relHum, weaBus.relHum)

  connect(souSelRad.HDirNor, weaBus.HDirNor)
  connect(souSelRad.HDifHor, weaBus.HDifHor)

  connect(souSelRad.HGloHor, weaBus.HGloHor)

  connect(cheTemBlaSky.TBlaSky, weaBus.TBlaSky)
  connect(limHorInfRad.HHorIR, weaBus.HHorIR)

  connect(limWinSpe.winSpe, weaBus.winSpe)

  connect(limWinDir.winDir, weaBus.winDir)

  connect(limCeiHei.ceiHei, weaBus.ceiHei)

  connect(limTotSkyCov.nTot, weaBus.nTot)
  connect(limOpaSkyCov.nOpa, weaBus.nOpa)

  connect(modTim.y, weaBus.cloTim)

  connect(solTim.solTim, weaBus.solTim)

  connect(altAng.alt, weaBus.solAlt)
  connect(zenAng.zen, weaBus.solZen)
  connect(decAng.decAng, weaBus.solDec)
  connect(solHouAng.solHouAng, weaBus.solHouAng)
  connect(longitude.y, weaBus.lon)
  connect(latitude.y, weaBus.lat)
  connect(altitude.y, weaBus.alt)
  connect(chePre.pAtm, weaBus.pAtm)

  connect(latitude.y, zenAng.lat)</code>.
</li>
<li>
May 30, 2014, by Michael Wetter:<br/>
Removed undesirable annotation <code>Evaluate=true</code>.
</li>
<li>
May 5, 2013, by Thierry S. Nouidui:<br/>
Added the option to use a constant, an input signal or the weather file as the source
for the ceiling height, the total sky cover, the opaque sky cover, the dew point temperature,
and the infrared horizontal radiation <code>HInfHor</code>.
</li>
<li>
October 8, 2013, by Michael Wetter:<br/>
Improved the algorithm that determines the absolute path of the file.
Now weather files are searched in the path specified, and if not found, the urls
<code>file://</code>, <code>modelica://</code> and <code>modelica://AixLib</code>
are added in this order to search for the weather file.
This allows using the data reader without having to specify an absolute path,
as long as the <code>AixLib</code> library
is on the <code>MODELICAPATH</code>.
This change was implemented in
<a href=\"modelica://AixLib.BoundaryConditions.WeatherData.BaseClasses.getAbsolutePath\">
AixLib.BoundaryConditions.WeatherData.BaseClasses.getAbsolutePath</a>
and improves this weather data reader.
</li>
<li>
May 2, 2013, by Michael Wetter:<br/>
Added function call to <code>getAbsolutePath</code>.
</li>
<li>
October 16, 2012, by Michael Wetter:<br/>
Added computation of the wet bulb temperature.
Computing the wet bulb temperature introduces a nonlinear
equation. As we have not observed an increase in computing time
because of computing the wet bulb temperature, it is computed
by default. By setting the parameter
<code>computeWetBulbTemperature=false</code>, the computation of the
wet bulb temperature can be removed.
Revised documentation.
</li>
<li>
August 11, 2012, by Wangda Zuo:<br/>
Renamed <code>radHor</code> to <code>radHorIR</code> and
improved the optional inputs for radiation data.
</li>
<li>
July 24, 2012, by Wangda Zuo:<br/>
Corrected the notes of SI unit requirements for input files.
</li>
<li>
July 13, 2012, by Michael Wetter:<br/>
Removed assignment of <code>HGloHor_in</code> in its declaration,
because this gives an overdetermined system if the input connector
is used.
Removed non-required assignments of attribute <code>displayUnit</code>.
</li>
<li>
February 25, 2012, by Michael Wetter:<br/>
Added subbus for solar position, which is needed by irradition and
shading model.
</li>
<li>
November 29, 2011, by Michael Wetter:<br/>
Fixed wrong display unit for <code>pAtm_in_internal</code> and
made propagation of parameter final.
</li>
<li>
October 27, 2011, by Wangda Zuo:<br/>
<ol>
<li>
Added optional connectors for dry bulb temperature, relative humidity, wind speed, wind direction, global horizontal radiation, diffuse horizontal radiation.<br/>
</li>
<li>
Separate the unit conversion for TMY3 data and data validity check.
</li>
</ol>
</li>
<li>
October 3, 2011, by Michael Wetter:<br/>
Propagated value for sky temperature calculation to make it accessible as a parameter.
</li>
<li>
July 20, 2011, by Michael Wetter:<br/>
Added the option to use a constant, an input signal or the weather file as the source
for the atmospheric pressure.
</li><li>
March 15, 2011, by Wangda Zuo:<br/>
Delete the wet bulb temperature since it may cause numerical problem.
</li>
<li>
March 7, 2011, by Wangda Zuo:<br/>
Added wet bulb temperature. Changed reader to read only needed columns.
Added explanation for 30 minutes shift for radiation data.
</li>
<li>
March 5, 2011, by Michael Wetter:<br/>
Changed implementation to obtain longitude and time zone directly
from weather file.
</li>
<li>
June 25, 2010, by Wangda Zuo:<br/>
First implementation.
</li>
</ul>
</html>"),
    Diagram(coordinateSystem(preserveAspectRatio=false,
     extent={{-200,-300},{300,300}})),
   __Dymola_LockedEditing="Model from IBPSA");
end ReaderTMY3;


Check the validity of the black-body sky temperature data. This component checks the value of the black-body sky temperature.
If the temperature is outside TMin and TMax,
the simulation will stop with an error.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckBlackBodySkyTemperature
  "Check the validity of the black-body sky temperature data"
  extends Modelica.Blocks.Icons.Block;

  parameter Modelica.Units.SI.Temperature TMin(displayUnit="degC") = 203.15
    "Minimum allowed temperature";
  parameter Modelica.Units.SI.Temperature TMax(displayUnit="degC") = 343.15
    "Maximum allowed temperature";

  Modelica.Blocks.Interfaces.RealInput TIn(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Black-body sky temperature"

  Modelica.Blocks.Interfaces.RealOutput TBlaSky(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Black-body sky temperature"

equation
  TBlaSky = TIn;
  assert(noEvent(TIn > TMin and TIn < TMax),
    "In " + getInstanceName() + ": Weather data black-body sky temperature out of bounds.\n" + "   TIn = " +
     String(TIn));
end CheckBlackBodySkyTemperature;


Ensures that the ceiling height is above a lower bound. This component ensures that the ceiling height is at least <i>0</i>
  meters.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckCeilingHeight
  "Ensures that the ceiling height is above a lower bound"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput ceiHeiIn(
    final quantity="Height",
    final unit="m") "Input ceiling height"
  Modelica.Blocks.Interfaces.RealOutput ceiHeiOut(
    final quantity="Height",
    final unit="m") "Ceiling height"
  constant Modelica.Units.SI.Height ceiHeiMin=0
    "Minimum allowed ceiling height";
equation
  ceiHeiOut = AixLib.Utilities.Math.Functions.smoothMax(
    ceiHeiIn,
    ceiHeiMin,
    0.1);
end CheckCeilingHeight;


Check the validity of the dew point temperature data. This component checks the value of temperature.
If the temperature is outside TMin and TMax,
the simulation will stop with an error.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckDewPointTemperature
  "Check the validity of the dew point temperature data"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput TIn(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Input Temperature"
  Modelica.Blocks.Interfaces.RealOutput TDewPoi(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Dew point temperature"

  parameter Modelica.Units.SI.Temperature TMin(displayUnit="degC") = 203.15
    "Minimum allowed temperature";
  parameter Modelica.Units.SI.Temperature TMax(displayUnit="degC") = 343.15
    "Maximum allowed temperature";

equation
  TDewPoi = TIn;
  assert(noEvent(TIn > TMin and TIn < TMax), "In " + getInstanceName() +
     ": Weather data dew point temperature out of bounds.\n" + "   TIn = " + String(
    TIn));
end CheckDewPointTemperature;


Check the validity of the dry bulb temperature data. This component checks the value of the dry bulb temperature.
If the temperature is outside TMin and TMax,
the simulation will stop with an error.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckDryBulbTemperature
  "Check the validity of the dry bulb temperature data"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput TIn(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Input Temperature"
  Modelica.Blocks.Interfaces.RealOutput TDryBul(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Dry bulb temperature"

  parameter Modelica.Units.SI.Temperature TMin(displayUnit="degC") = 203.15
    "Minimum allowed temperature";
  parameter Modelica.Units.SI.Temperature TMax(displayUnit="degC") = 343.15
    "Maximum allowed temperature";

equation
  TDryBul = TIn;
  assert(noEvent(TIn > TMin and TIn < TMax), "In " + getInstanceName() +
     ": Weather data dry bulb temperature out of bounds.\n" + "   TIn = " + String(
    TIn));
end CheckDryBulbTemperature;


Ensure that the radiation is not smaller than 0. This block ensures that the radiation is not smaller than <i>0</i>.
  The Modelica data reader will interpolate data when it reads the data
  from a file. Thus, it is possible to generate negative values due to
  the interpolation.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckIRRadiation "Ensure that the radiation is not smaller than 0"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput HIn(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2") "Input horizontal infrared irradiation"
  Modelica.Blocks.Interfaces.RealOutput HOut(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2") "Horizontal infrared irradiation"

  constant Modelica.Units.SI.RadiantEnergyFluenceRate HMin=0.0001
    "Minimum value for radiation";
equation
  HOut = AixLib.Utilities.Math.Functions.smoothMax(
    x1=HIn,
    x2=HMin,
    deltaX=HMin/10);
end CheckIRRadiation;


Ensures that the interpolated pressure is between prescribed bounds. This component ensures that the interpolated pressure is between 31,000 Pa and 120,000 Pa.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckPressure
  "Ensures that the interpolated pressure is between prescribed bounds"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput PIn(
    final quantity="Pressure",
    final unit="Pa") "Atmospheric pressure"
  Modelica.Blocks.Interfaces.RealOutput pAtm(
    final quantity="Pressure",
    final unit="Pa") "Atmospheric pressure"
  constant Modelica.Units.SI.Pressure PMin=3100 "Minimum allowed pressure";
  constant Modelica.Units.SI.Pressure PMax=120000 "Maximum allowed pressure";
equation
  pAtm = PIn;
  assert(noEvent(PIn > PMin and PIn < PMax), "In " + getInstanceName() +
    ": Weather data atmospheric pressure out of bounds.\n" + "   PIn = " + String(PIn));
end CheckPressure;


within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckRadiation "Ensure that the radiation is not smaller than 0"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput HIn(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2") "Input radiation"
  Modelica.Blocks.Interfaces.RealOutput HOut(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2") "Radiation"

  constant Modelica.Units.SI.RadiantEnergyFluenceRate HMin=0.0001
    "Minimum value for radiation";
equation
  HOut = AixLib.Utilities.Math.Functions.smoothMax(
    x1=HIn,
    x2=HMin,
    deltaX=HMin/10);
end CheckRadiation;


Check the validity of relative humidity. This component constrains the value of relative humidity to a range
  of <i>[0, 1]</i>.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckRelativeHumidity "Check the validity of relative humidity"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput relHumIn(final unit="1")
    "Input relative humidity"
  Modelica.Blocks.Interfaces.RealOutput relHumOut(final unit="1")
    "Relative humidity"
  constant Real delta=0.01 "Smoothing parameter";
protected
  constant Real relHumMin=delta "Lower bound";
  constant Real relHumMax=1 - delta "Upper bound";

equation
  relHumOut = AixLib.Utilities.Math.Functions.smoothLimit(
    relHumIn,
    relHumMin,
    relHumMax,
    delta/10);
end CheckRelativeHumidity;


Constrains the sky cover to [0, 1]. This component constrains the interpolated sky cover between 0
  and 1.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckSkyCover "Constrains the sky cover to [0, 1]"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput nIn(min=0, max=1)
    "Input sky cover [0, 10]"
  Modelica.Blocks.Interfaces.RealOutput nOut(min=0, max=1, unit="1")
    "Sky cover [0, 1]"

  constant Real delta=0.01 "Smoothing parameter";
protected
  constant Real nMin=delta "Lower bound";
  constant Real nMax=10 - delta "Upper bound";
equation
  nOut = AixLib.Utilities.Math.Functions.smoothLimit(
    nIn,
    nMin,
    nMax,
    delta/10);
end CheckSkyCover;


Check the validity of temperature data. This component checks the value of temperature. If the temperature is
  outside TMin and TMax, the simulation will
  stop with an error.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckTemperature "Check the validity of temperature data"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput TIn(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Input Temperature"
  Modelica.Blocks.Interfaces.RealOutput TOut(
    final quantity="ThermodynamicTemperature",
    final unit="K",
    displayUnit="degC") "Output temperature"

  parameter Modelica.Units.SI.Temperature TMin(displayUnit="degC") = 203.15
    "Minimum allowed temperature";
  parameter Modelica.Units.SI.Temperature TMax(displayUnit="degC") = 343.15
    "Maximum allowed temperature";

equation
  TOut = TIn;
  assert(TOut > TMin, "Temperature out of bounds.\n" + "   TOut = " + String(
    TOut));
  assert(TOut < TMax, "Temperature out of bounds.\n" + "   TOut = " + String(
    TOut));
end CheckTemperature;


Constrains the wind direction to [0, 2*pi] degree. This component constrains the interpolated wind direction between
  0 and 360 degree.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckWindDirection "Constrains the wind direction to [0, 2*pi] degree"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput nIn(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Input wind direction"
  Modelica.Blocks.Interfaces.RealOutput nOut(
    final quantity="Angle",
    final unit="rad",
    displayUnit="deg") "Wind direction"

  constant Real delta=0.01 "Smoothing parameter";
protected
  constant Real nMin=0 "Lower bound";
  constant Real nMax=2*Modelica.Constants.pi "Upper bound";
equation
  nOut = AixLib.Utilities.Math.Functions.smoothLimit(
    nIn,
    nMin,
    nMax,
    delta/10);
end CheckWindDirection;


Ensures that the wind speed is non-negative. This component ensures that the wind speed is non-negative.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block CheckWindSpeed "Ensures that the wind speed is non-negative"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput winSpeIn(final quantity="Velocity",
      final unit="m/s") "Input wind speed"
  Modelica.Blocks.Interfaces.RealOutput winSpeOut(final quantity="Velocity",
      final unit="m/s") "Wind speed"
  constant Modelica.Units.SI.Velocity winSpeMin=1e-6
    "Minimum allowed wind speed";

equation
  // Modelica Table will interpolate data when it reads the weather data file.
  // It can generate negative values due to the interpolation.
  winSpeOut = AixLib.Utilities.Math.Functions.smoothMax(
    x1=winSpeIn,
    x2=winSpeMin,
    deltaX=winSpeMin/10);
end CheckWindSpeed;


Convert the unit of solar radiation received from the TMY3 data file. The TMY3 data for solar radiation is the radiation accumulated in one
  hour. Thus, it used a unit of Wh/m2. This component
  converts Wh/m2 to W/m2 that is the standard
  unit in Modelica.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block ConvertRadiation
  "Convert the unit of solar radiation received from the TMY3 data file"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput HIn(final unit="W.h/m2")
    "Input radiation"
  Modelica.Blocks.Interfaces.RealOutput HOut(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2") "Radiation"

protected
  constant Modelica.Units.SI.Time Hou=3600 "1 hour";

equation
  HOut =HIn/Modelica.Units.Conversions.to_hour(Hou);
end ConvertRadiation;


Convert the relative humidity from percentage to real. This component converts the relative humidity from percentage to
  real. Input is the relative humidity in percentage, as this is the
  data format that is used in the Typical Meteorological Year weather
  data.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block ConvertRelativeHumidity
  "Convert the relative humidity from percentage to real"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput relHumIn(unit="1")
    "Value of relative humidity in percentage"
  Modelica.Blocks.Interfaces.RealOutput relHumOut(unit="1")
    "Relative humidity between 0 and 1"
equation
  relHumOut = relHumIn/100;
end ConvertRelativeHumidity;


Converts the simulation time to calendar time in scale of 1 year (365 days), or a multiple of a year. This component converts the simulation time to calendar time in a scale of 1 year (365 days),
or a multiple of it, if this is the length of the weather file.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block ConvertTime
  "Converts the simulation time to calendar time in scale of 1 year (365 days), or a multiple of a year"
  extends PartialConvertTime;
  Modelica.Blocks.Interfaces.RealInput modTim(
    final quantity="Time",
    final unit="s") "Simulation time"
  Modelica.Blocks.Interfaces.RealOutput calTim(
    final quantity="Time",
    final unit="s") "Calendar time"

protected
  constant Modelica.Units.SI.Time shiftSolarRad=1800
    "Number of seconds for the shift for solar radiation calculation";

equation
  calTim = calTimAux;
  modTimAux = modTim;
  assert(canRepeatWeatherFile or noEvent((time - weaDatEndTim) < shiftSolarRad),
    "In " + getInstanceName() + ": Insufficient weather data provided for the desired simulation period.
    The simulation time " + String(time) +
    " exceeds the end time " + String(weaDatEndTim) + " of the weather data file.",
    AssertionLevel.error);

  assert(canRepeatWeatherFile or noEvent(time >= weaDatStaTim),
    "In " + getInstanceName() + ": Insufficient weather data provided for the desired simulation period.
    The simulation time " + String(time) +
    " is less than the start time " + String(weaDatStaTim) + " of the weather data file.",
    AssertionLevel.error);
end ConvertTime;


Equation of time. This component computes the difference between solar noon and noon of local civil time.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block EquationOfTime "Equation of time"
  extends PartialConvertTime;
  Modelica.Blocks.Interfaces.RealInput nDay(
    quantity="Time",
    unit="s")
    "Zero-based day number in seconds (January 1=0, January 2=86400)"
  Modelica.Blocks.Interfaces.RealOutput eqnTim(
    final quantity="Time",
    final unit="s",
    displayUnit="min") "Equation of time"
protected
  Real Bt "Intermediate variable";
equation
  modTimAux = nDay;
  Bt = Modelica.Constants.pi*((calTimAux + 86400)/86400 - 81)/182
    "Our unit is s instead of day in (A.4.2b)";
  eqnTim = 60*(9.87*Modelica.Math.sin(2*Bt) - 7.53*Modelica.Math.cos(Bt) - 1.5*
    Modelica.Math.sin(Bt)) "Our unit is s instead of min in (A.4.2a)";
end EquationOfTime;


Block that limits the relative humidity. Block that limits the cloud cover ceiling height to be positive.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block LimiterCeilingHeight "Block that limits the relative humidity"
  extends PartialLimiterMin;

  Modelica.Blocks.Interfaces.RealOutput ceiHei(
    final unit="m") = max(0, u) "Cloud cover ceiling height"
end LimiterCeilingHeight;


Block that limits the horizontal infrared irradiation. Block that limits the horizontal infrared irradiation to be positive.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block LimiterHorizontalInfraredIrradiation
  "Block that limits the horizontal infrared irradiation"
  extends PartialLimiterMin;

  Modelica.Blocks.Interfaces.RealOutput HHorIR(
    final unit="W/m2") = max(0, u) "Horizontal infrared irradiation"
end LimiterHorizontalInfraredIrradiation;


Block that limits the opaque sky cover. Block that limits the opaque sky cover.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block LimiterOpaqueSkyCover "Block that limits the opaque sky cover"
  extends PartialLimiter;

  Modelica.Blocks.Interfaces.RealOutput nOpa(
    final unit="1") "Opaque sky cover"

equation
  nOpa = min(uMax, max(uMin, u));
end LimiterOpaqueSkyCover;


Block that limits the relative humidity. Block that limits the relative humidity.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block LimiterRelativeHumidity "Block that limits the relative humidity"
  extends PartialLimiter;

  Modelica.Blocks.Interfaces.RealOutput relHum(
    final unit="1") "Relative humidity"

equation
  relHum = min(uMax, max(uMin, u));
end LimiterRelativeHumidity;


Block that limits the total sky cover. Block that limits the total sky cover.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block LimiterTotalSkyCover "Block that limits the total sky cover"
  extends PartialLimiter;

  Modelica.Blocks.Interfaces.RealOutput nTot(
    final unit="1") "Total sky cover"

equation
  nTot = min(uMax, max(uMin, u));
end LimiterTotalSkyCover;


Block that limits the wind direction. Block that limits the wind direction.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block LimiterWindDirection "Block that limits the wind direction"
  extends PartialLimiter(
    final uMax=2*Modelica.Constants.pi);

  Modelica.Blocks.Interfaces.RealOutput winDir(
    final unit="rad") "Wind direction"

equation
  winDir = min(uMax, max(uMin, u));
end LimiterWindDirection;


Block that limits the wind speed. Block that limits the wind speed to be positive.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block LimiterWindSpeed "Block that limits the wind speed"
  extends PartialLimiterMin;

  Modelica.Blocks.Interfaces.RealOutput winSpe(
    final unit="m/s") = max(0, u) "Wind speed"
end LimiterWindSpeed;


Converts the clock time to local civil time.. This component converts the clock time to local civil time.
The parameter timZon represents the time zone of the facility  (relative to Greenwich Mean Time or the 0th meridian). Time zones west of GMT (e.g. North America) are represented as negative;
east of GMT as positive. Fraction of hours are represented in decimals (e.g. for 6:30, use 6.5).

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block LocalCivilTime "Converts the clock time to local civil time."
  extends PartialConvertTime;
  Modelica.Blocks.Interfaces.RealInput cloTim(
    final quantity="Time",
    final unit="s") "Clock time"
  parameter Modelica.Units.SI.Time timZon(displayUnit="h") "Time zone";
  parameter Modelica.Units.SI.Angle lon(displayUnit="deg") "Longitude";
  Modelica.Blocks.Interfaces.RealOutput locTim(
    final quantity="Time",
    final unit="s") "Local civil time"
protected
  final parameter Modelica.Units.SI.Time diff=-timZon + lon*43200/Modelica.Constants.pi
    "Difference between local and clock time";
equation
  modTimAux = cloTim;
  locTim = calTimAux + diff;
end LocalCivilTime;


within AixLib.BoundaryConditions.WeatherData;
package BaseClasses "Package with base classes for AixLib.BoundaryConditions.WeatherData"
  extends Modelica.Icons.BasesPackage;
end BaseClasses;


within AixLib.BoundaryConditions.WeatherData.BaseClasses;
partial block PartialConvertTime
  "Converts the simulation time to calendar time in scale of 1 year (365 days), or a multiple of a year"
  extends Modelica.Blocks.Icons.Block;
  parameter Modelica.Units.SI.Time weaDatStaTim(displayUnit="d") = 0
    "Start time of weather data";
  parameter Modelica.Units.SI.Time weaDatEndTim(displayUnit="d") = 31536000
    "End time of weather data";
  Modelica.Units.SI.Time modTimAux "Model time";
  Modelica.Units.SI.Time calTimAux "Calendar time";

protected
  parameter Modelica.Units.SI.Time lenWea=weaDatEndTim - weaDatStaTim
    "Length of weather data";

  parameter Boolean canRepeatWeatherFile = abs(mod(lenWea, 365*24*3600)) < 1E-2
    "=true, if the weather file can be repeated, since it has the length of a year or a multiple of it";

  discrete Modelica.Units.SI.Time tNext(start=0, fixed=true)
    "Start time of next period";

equation
  when {initial(), canRepeatWeatherFile and modTimAux > pre(tNext)} then
    // simulation time stamp went over the end time of the weather file
    //(last time stamp of the weather file + average increment)
    tNext = if canRepeatWeatherFile then integer(modTimAux/lenWea)*lenWea + lenWea else time;
  end when;
  calTimAux = if canRepeatWeatherFile then modTimAux - tNext + lenWea else modTimAux;
end PartialConvertTime;


Partial block to limit a signal. Block that computes y_internal=min(uMax, max(uMin, u)),
where y_internal is a protected connector.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
partial block PartialLimiter
  "Partial block to limit a signal"
  extends Modelica.Blocks.Icons.Block;

  constant Real uMin = 0 "Minimum value";
  constant Real uMax = 1 "Maximum value";

  Modelica.Blocks.Interfaces.RealInput u "Connector of Real input signal"
end PartialLimiter;


Partial block to limit a signal. Partial block that is used to limit a signal by a minimum value.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
partial block PartialLimiterMin
  "Partial block to limit a signal"
  extends Modelica.Blocks.Icons.Block;

  Modelica.Blocks.Interfaces.RealInput u "Connector of Real input signal"
end PartialLimiterMin;


Solar time. This component computes the local solar time.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block SolarTime "Solar time"
  extends Modelica.Blocks.Icons.Block;
  Modelica.Blocks.Interfaces.RealInput locTim(quantity="Time", unit="s")
    "Local time"
  Modelica.Blocks.Interfaces.RealInput equTim(quantity="Time", unit="s")
    "Equation of time"
  Modelica.Blocks.Interfaces.RealOutput solTim(
    final quantity="Time",
    final unit="s",
    displayUnit="s") "Solar time"
equation
  solTim = locTim + equTim "Our unit is s in stead of h in (A.4.3)";
end SolarTime;


Block that selects as its output either a parameter value or its input. Block that produces at its output the input value uCon, uFil
or the parameter value p depending on the parameter value
datSou.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block SourceSelector
  "Block that selects as its output either a parameter value or its input"
  extends Modelica.Blocks.Interfaces.SO;
  parameter AixLib.BoundaryConditions.Types.DataSource datSou "Data source"
  parameter Real p "Parameter value";
  Modelica.Blocks.Interfaces.RealInput uFil
   if datSou == AixLib.BoundaryConditions.Types.DataSource.File
    "Input signal from file reader"
  Modelica.Blocks.Interfaces.RealInput uCon
  if datSou == AixLib.BoundaryConditions.Types.DataSource.Input
    "Input signal from input connector"
equation
  if datSou == AixLib.BoundaryConditions.Types.DataSource.Parameter then
    y = p;
  end if;
  connect(uCon, y);
  connect(uFil, y);
end SourceSelector;


Block that selects the solar radiation source and outputs the solar radiation quantities. Block that outputs the direct normal, diffuse horizontal and diffuse global
solar irradiation.
This block computes these output quantities based on conditionally provided
input signals.

within AixLib.BoundaryConditions.WeatherData.BaseClasses;
block SourceSelectorRadiation
  "Block that selects the solar radiation source and outputs the solar radiation quantities"
  extends Modelica.Blocks.Icons.Block;
  parameter AixLib.BoundaryConditions.Types.RadiationDataSource datSou "Data source"

  Modelica.Blocks.Interfaces.RealInput HDirNorFil(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
   if datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.File
    "Direct normal solar irradiation from weather data file"

  Modelica.Blocks.Interfaces.RealInput HDirNorIn(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
   if datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HDirNor_HDifHor or
      datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HDirNor_HGloHor
    "Direct normal solar irradiation from input connector"

  Modelica.Blocks.Interfaces.RealInput HDifHorFil(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
  if datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.File
    "Diffuse horizontal solar irradiation from weather data file"

  Modelica.Blocks.Interfaces.RealInput HDifHorIn(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
  if datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HGloHor_HDifHor or
     datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HDirNor_HDifHor
    "Diffuse horizontal solar irradiation from input connector"

  Modelica.Blocks.Interfaces.RealInput HGloHorFil(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
   if datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.File
    "Global horizontal solar irradiation from weather data file"

  Modelica.Blocks.Interfaces.RealInput HGloHorIn(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
   if datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HGloHor_HDifHor or
      datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HDirNor_HGloHor
    "Global horizontal solar irradiation from input connector"

  Modelica.Blocks.Interfaces.RealInput zen(
    final quantity="Angle",
    final unit="rad")
    "Zenith angle"

  Modelica.Blocks.Interfaces.RealOutput HDirNor(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
    "Direct normal solar irradiation"
  Modelica.Blocks.Interfaces.RealOutput HDifHor(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
    "Diffuse horizontal solar irradiation"
  Modelica.Blocks.Interfaces.RealOutput HGloHor(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2")
    "Global horizontal solar irradiation"

protected
  constant Real epsCos = 1e-6 "Small value to avoid division by 0";
  constant Modelica.Units.SI.HeatFlux solCon=1367.7 "Solar constant";

  // Conditional connectors
  Modelica.Blocks.Interfaces.RealInput HGloHor_in_internal(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2") "Needed to connect to conditional connector";
  Modelica.Blocks.Interfaces.RealInput HDifHor_in_internal(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2") "Needed to connect to conditional connector";
  Modelica.Blocks.Interfaces.RealInput HDirNor_in_internal(
    final quantity="RadiantEnergyFluenceRate",
    final unit="W/m2") "Needed to connect to conditional connector";

equation
  // Conditional connect statements
  connect(HGloHor_in_internal, HGloHorFil);
  connect(HDifHor_in_internal, HDifHorFil);
  connect(HDirNor_in_internal, HDirNorFil);
  connect(HGloHor_in_internal, HGloHorIn);
  connect(HDifHor_in_internal, HDifHorIn);
  connect(HDirNor_in_internal, HDirNorIn);

  //---------------------------------------------------------------------------
  // Select global horizontal radiation connector
  if datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HDirNor_HDifHor then
    HGloHor = max(0, HDirNor_in_internal*cos(zen)+HDifHor_in_internal)
      "Calculate the HGloHor using HDirNor and HDifHor according to (A.4.14) and (A.4.15)";
    HGloHor_in_internal = 0;
  else
    HGloHor = max(0, HGloHor_in_internal)
      "Get HGloHor using weather data file or input connector of weather data reader";
  end if;

  //---------------------------------------------------------------------------
  // Select diffuse horizontal radiation connector
  if datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HDirNor_HGloHor then
    HDifHor = max(0, HGloHor_in_internal - HDirNor_in_internal*cos(zen))
      "Calculate the HGloHor using HDirNor and HDifHor according to (A.4.14) and (A.4.15)";
    HDifHor_in_internal = 0;
  else
    HDifHor = max(0, HDifHor_in_internal)
      "Get HDifHor using weather data file or input connector of weather data reader";
  end if;

  //---------------------------------------------------------------------------
  // Select direct normal radiation connector
  if datSou == AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HGloHor_HDifHor then
      HDirNor = max(0, min(
        solCon,
        (HGloHor_in_internal -HDifHor_in_internal)*
          AixLib.Utilities.Math.Functions.spliceFunction(
            x=cos(zen),
            pos=AixLib.Utilities.Math.Functions.inverseXRegularized(cos(zen), epsCos),
            neg=0,
            deltax=epsCos)))
      "Calculate the HDirNor using HGloHor and HDifHor according to (A.4.14) and (A.4.15)";
    HDirNor_in_internal = 0;
  else
    HDirNor = max(0, HDirNor_in_internal)
      "Get HDirNor using weather data file or input connector of weather data reader";
  end if;
end SourceSelectorRadiation;


Test model for CheckBlackBodySkyTemperature. This example tests the model that checks the black-body sky temperature.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model CheckBlackBodySkyTemperature
  "Test model for CheckBlackBodySkyTemperature"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckBlackBodySkyTemperature
    cheSkyBlaBodTem "Check for the black body sky temperature"
  Modelica.Blocks.Sources.Ramp TBlaBod(
    height=140-0.02,
    duration=1,
    offset=273.15 - 69.99) "Black body sky temperature"
equation
  connect(TBlaBod.y, cheSkyBlaBodTem.TIn)
end CheckBlackBodySkyTemperature;


Test model for ceiling height check. This example tests the model that constrains the ceiling height.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model CheckCeilingHeight "Test model for ceiling height check"
  extends Modelica.Icons.Example;
  AixLib.Utilities.Time.ModelTime modTim
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckCeilingHeight
    cheCeiHei "Block that constrains the ceiling height"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTim(
    weaDatStaTim=0,
    weaDatEndTim=31536000)
    "Block that converts time"
protected
  Modelica.Blocks.Tables.CombiTable1Ds datRea(
    tableOnFile=true,
    tableName="tab1",
    fileName=Modelica.Utilities.Files.loadResource(
       Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")),
    columns=2:30,
    smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative)
    "Data reader"
equation
  connect(datRea.y[20], cheCeiHei.ceiHeiIn)
  connect(modTim.y, conTim.modTim)
  connect(conTim.calTim, datRea.u)
end CheckCeilingHeight;


Test model for pressure check. This example tests the model that asserts that the pressure is within acceptable bounds.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model CheckPressure "Test model for pressure check"
  extends Modelica.Icons.Example;

  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckPressure chePre
    "Block that checks the pressure"
  AixLib.Utilities.Time.ModelTime modTim
    "Block that outputs simulation time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTim(
    weaDatStaTim=0,
    weaDatEndTim=31536000)
    "Block that converts time"
protected
  Modelica.Blocks.Tables.CombiTable1Ds datRea(
    tableOnFile=true,
    tableName="tab1",
    fileName=Modelica.Utilities.Files.loadResource(
       Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")),
    columns=2:30,
    smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative)
    "Data reader"
equation
  connect(datRea.y[4], chePre.PIn)
  connect(modTim.y, conTim.modTim)
  connect(conTim.calTim, datRea.u)
end CheckPressure;


Test model for CheckRadiation. This example tests the model that constrains the radiation.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model CheckRadiation "Test model for CheckRadiation"
  extends AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples.ConvertRadiation;
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckRadiation cheGloRad
    "Check global horizontal radiation"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckRadiation cheDifRad
    "Check diffuse horizontal radiation"
equation

  connect(conGloRad.HOut, cheGloRad.HIn)
  connect(conDifRad.HOut, cheDifRad.HIn)
end CheckRadiation;


Test model for CheckRelativeHumidity. This example tests the model that constrains the relative humidity.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model CheckRelativeHumidity "Test model for CheckRelativeHumidity"
  extends AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples.ConvertRelativeHumidity;

  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckRelativeHumidity cheRelHum
    "Block that constrains the relative humidity"
equation
  connect(conRelHum.relHumOut, cheRelHum.relHumIn)
end CheckRelativeHumidity;


Test model for checking sky cover. This example tests the model that constrains the sky cover.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model CheckSkyCover "Test model for checking sky cover"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckSkyCover
    cheTotSkyCov "Check total sky cover"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckSkyCover
    cheOpaSkyCov "Check opaque sky cover"
protected
  AixLib.Utilities.Time.ModelTime modTim "Generate simulation time"

  Modelica.Blocks.Tables.CombiTable1Ds datRea(
    tableOnFile=true,
    tableName="tab1",
    fileName=Modelica.Utilities.Files.loadResource(
       Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")),
    columns=2:30,
    smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative)
    "Data reader"

  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTim(
    weaDatStaTim=0,
    weaDatEndTim=31536000)

  Modelica.Blocks.Math.Gain conTotSkyCov(final k=0.1)
    "Convert sky cover from [0...10] to [0...1]"
  Modelica.Blocks.Math.Gain conOpaSkyCov1(final k=0.1)
    "Convert sky cover from [0...10] to [0...1]"
equation
  connect(modTim.y, conTim.modTim)
  connect(conTim.calTim, datRea.u)
  connect(datRea.y[17], conTotSkyCov.u)
  connect(datRea.y[18], conOpaSkyCov1.u)
  connect(conTotSkyCov.y, cheTotSkyCov.nIn)
  connect(conOpaSkyCov1.y, cheOpaSkyCov.nIn)
end CheckSkyCover;


Test model for CheckTemperature. This example tests the model that checks the temperature.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model CheckTemperature "Test model for CheckTemperature"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckDryBulbTemperature
    cheTemDryBul "Check dry bulb temperature "
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckDewPointTemperature
    cheTemDewPoi "Check dew point temperature"
  AixLib.Utilities.Time.ModelTime modTim
    "Block that outputs the model time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTim(
    weaDatStaTim=0,
    weaDatEndTim=31536000)
    "Block that converts time"
  Modelica.Blocks.Math.UnitConversions.From_degC from_degC
    "Block that converts temperature"
  Modelica.Blocks.Math.UnitConversions.From_degC from_degC1
    "Block that converts temperature"
protected
  Modelica.Blocks.Tables.CombiTable1Ds datRea(
    tableOnFile=true,
    tableName="tab1",
    fileName=Modelica.Utilities.Files.loadResource(
       Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")),
    columns=2:30,
    smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative)
    "Data reader"
equation
  connect(modTim.y, conTim.modTim)
  connect(conTim.calTim, datRea.u)
  connect(datRea.y[1], from_degC.u)
  connect(from_degC.y, cheTemDryBul.TIn)
  connect(datRea.y[2], from_degC1.u)
  connect(from_degC1.y, cheTemDewPoi.TIn)
end CheckTemperature;


Test model for wind direction check. This example tests the model that constrains the wind direction.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model CheckWindDirection "Test model for wind direction check"
  extends Modelica.Icons.Example;
  AixLib.Utilities.Time.ModelTime modTim
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckWindDirection
    cheWinDir "Block that constrains the wind direction"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTim(
    weaDatStaTim=0,
    weaDatEndTim=31536000)
    "Block that converts time"
  Modelica.Blocks.Math.UnitConversions.From_deg from_deg
    "Block that converts temperature"
protected
  Modelica.Blocks.Tables.CombiTable1Ds datRea(
    tableOnFile=true,
    tableName="tab1",
    fileName=Modelica.Utilities.Files.loadResource(
       Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")),
    columns=2:30,
    smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative)
    "Data reader"
equation
  connect(modTim.y, conTim.modTim)
  connect(conTim.calTim, datRea.u)
  connect(datRea.y[15], from_deg.u)
  connect(from_deg.y, cheWinDir.nIn)
end CheckWindDirection;


Test model for wind speed check. This example tests the model that constrains the wind speed.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model CheckWindSpeed "Test model for wind speed check"
  extends Modelica.Icons.Example;
  AixLib.Utilities.Time.ModelTime modTim
    "Block that outputs simulation time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.CheckWindSpeed cheWinSpe
    "Block that constrains the wind speed"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTim(
    weaDatStaTim=0,
    weaDatEndTim=31536000)
    "Block that converts time"
protected
  Modelica.Blocks.Tables.CombiTable1Ds datRea(
    tableOnFile=true,
    tableName="tab1",
    fileName=Modelica.Utilities.Files.loadResource(
       Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")),
    columns=2:30,
    smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative)
    "Data reader"
equation
  connect(datRea.y[16], cheWinSpe.winSpeIn)
  connect(modTim.y, conTim.modTim)
  connect(conTim.calTim, datRea.u)
end CheckWindSpeed;


Test model for ConvertRadiation. This example tests the model that converts radiation.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model ConvertRadiation "Test model for ConvertRadiation"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertRadiation
    conGloRad "Convert units for global horizontal radiation"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertRadiation
    conDifRad "Convert units for diffuse horizontal radiation"
  AixLib.Utilities.Time.ModelTime modTim
    "Block that outputs simulation time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime timCon(
    weaDatStaTim=0,
    weaDatEndTim=31536000)
    "Convert simmulation time to calendar time"
protected
  Modelica.Blocks.Tables.CombiTable1Ds datRea(
    tableOnFile=true,
    tableName="tab1",
    fileName=Modelica.Utilities.Files.loadResource(
       Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")),
    columns=2:30,
    smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative)
    "Data reader"

equation
  connect(timCon.calTim, datRea.u)
  connect(datRea.y[8], conGloRad.HIn)
  connect(datRea.y[10], conDifRad.HIn)
  connect(modTim.y, timCon.modTim)
end ConvertRadiation;


Test model for converting relative humidity and checking its validity. This example tests the model that converts relative humidity.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model ConvertRelativeHumidity
  "Test model for converting relative humidity and checking its validity"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertRelativeHumidity conRelHum
    "Block that converts relative humidity"
  AixLib.Utilities.Time.ModelTime modTim
    "Block that outputs simulation time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTim(
    weaDatStaTim=0,
    weaDatEndTim=31536000)
    "Block that converts time"
protected
  Modelica.Blocks.Tables.CombiTable1Ds datRea(
    tableOnFile=true,
    tableName="tab1",
    fileName=Modelica.Utilities.Files.loadResource(
       Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")),
    columns=2:30,
    smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative)
    "Data reader"

equation
  connect(datRea.y[3], conRelHum.relHumIn)
  connect(modTim.y, conTim.modTim)
  connect(conTim.calTim, datRea.u)
end ConvertRelativeHumidity;


Test model for converting time. This example tests the model that converts time.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model ConvertTime "Test model for converting time"
  extends Modelica.Icons.Example;
  AixLib.Utilities.Time.ModelTime modTim
    "Block that outputs simulation time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTim(
    weaDatStaTim=0,
    weaDatEndTim=31536000)
    "Block that converts time"
equation
  connect(modTim.y, conTim.modTim)
end ConvertTime;


Validation of time conversion for negative start time. This example tests the model that converts time for negative start time.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model ConvertTimeNegativeStart
  "Validation of time conversion for negative start time"
  extends AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples.ConvertTime;
end ConvertTimeNegativeStart;


Validation of time conversion for positive start time. This example tests the model that converts time for positive start time.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model ConvertTimePositiveStart
  "Validation of time conversion for positive start time"
  extends AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples.ConvertTime;
end ConvertTimePositiveStart;


Test model for equation of time. This example tests the model that computes the equation of time.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model EquationOfTime "Test model for equation of time"
  extends Modelica.Icons.Example;
  Utilities.Time.ModelTime modTim "Block that outputs simulation time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.EquationOfTime eqnTim
    "Block that computes the equation of time"
equation
  connect(modTim.y, eqnTim.nDay)
end EquationOfTime;


Test model to get the absolute path of a URI. This model tests the function that gets the absolute path of a URI.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model GetAbsolutePath "Test model to get the absolute path of a URI"
  extends Modelica.Icons.Example;
  parameter String f = Modelica.Utilities.Files.loadResource("modelica://AixLib/package.mo")
   "Name of a file that exists";
  parameter String fAbs=
    AixLib.BoundaryConditions.WeatherData.BaseClasses.getAbsolutePath(uri=f)
    "Absolute path of f";
  final parameter Integer dummy = 1
    "Dummy variable, used to have a result as needed for the unit tests";
initial algorithm
  Modelica.Utilities.Streams.print("Absolute path = " + fAbs);
end GetAbsolutePath;


Test model to get Altitude of TMY3. This example tests getting the location altitude of a TMY3 weather data file.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model GetAltitudeTMY3 "Test model to get Altitude of TMY3"
  extends Modelica.Icons.Example;
  parameter String filNam = Modelica.Utilities.Files.loadResource(
  "modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")
    "Name of weather data file";
  parameter Modelica.Units.SI.Length alt = AixLib.BoundaryConditions.WeatherData.BaseClasses.getAltitudeLocationTMY3(
  filNam) "Altitude of TMY3 location";
end GetAltitudeTMY3;


Test model to get header element. This example tests getting the header of the TMY3 weather data file.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model GetHeaderElement "Test model to get header element"
  extends Modelica.Icons.Example;
  parameter Modelica.Units.SI.Angle longitude(fixed=false, displayUnit="deg")
    "Longitude";
  parameter Modelica.Units.SI.Angle latitude(fixed=false, displayUnit="deg")
    "Latitude";
  parameter Modelica.Units.SI.Time timeZone(fixed=false, displayUnit="h")
    "Time zone";

  parameter String filNam = Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")
    "Name of weather data file";

  final parameter String absFilNam = AixLib.BoundaryConditions.WeatherData.BaseClasses.getAbsolutePath(filNam)
    "Absolute path of the file";
initial equation
  longitude = AixLib.BoundaryConditions.WeatherData.BaseClasses.getLongitudeTMY3(
    filNam=absFilNam);
  latitude = AixLib.BoundaryConditions.WeatherData.BaseClasses.getLatitudeTMY3(
    filNam=absFilNam);
  timeZone = AixLib.BoundaryConditions.WeatherData.BaseClasses.getTimeZoneTMY3(
    filNam=absFilNam);
  assert(abs(longitude*180/Modelica.Constants.pi+87.92) < 1,
      "Error when parsing longitude, longitude = " + String(longitude));
  assert(abs(latitude*180/Modelica.Constants.pi-41.98) < 1,
      "Error when parsing latitude, latitude = " + String(latitude));
  assert(abs(timeZone+6*3600) < 1, "Error when parsing time zone, timeZone = "
    + String(timeZone));
end GetHeaderElement;


Test model to get the time span of a weather file. This example tests getting the time span of a TMY3 weather data file.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model GetTimeSpanTMY3 "Test model to get the time span of a weather file"
  extends Modelica.Icons.Example;

  parameter String filNam = Modelica.Utilities.Files.loadResource(
  "modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")
    "Name of weather data file";
  parameter String tabNam = "tab1" "Name of table on weather file";

  parameter Modelica.Units.SI.Time[2] timeSpan(each fixed=false)
    "Start time, end time of weather data";

protected
  constant Modelica.Units.SI.Time endTim=365*24*3600.;
  constant Modelica.Units.SI.Time staTim=0.;

initial equation
  timeSpan = AixLib.BoundaryConditions.WeatherData.BaseClasses.getTimeSpanTMY3(
  filNam, tabNam);

  assert(abs(timeSpan[2]-endTim) < 1E-5  and abs(timeSpan[1]-staTim) < 1E-5,
      "Error in weather file, start time " + String(timeSpan[1]) +
      " and end time " + String(timeSpan[2]) +
      ", but expected " + String(staTim) + " and " + String(endTim) + ".");
end GetTimeSpanTMY3;


Test model to get the time span of a weather file with a long header line. This example tests getting the time span of a TMY3 weather data file with a long line in the
header of the weather file.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model GetTimeSpanTMY3LongHeader
  "Test model to get the time span of a weather file with a long header line"
  extends Modelica.Icons.Example;

  parameter String filNam=Modelica.Utilities.Files.loadResource(
  "modelica://AixLib/Resources/Data/BoundaryConditions/WeatherData/BaseClasses/Examples/weatherWithLongHeader.mos")
   "Name of weather data file";

  final parameter Modelica.Units.SI.Time[2] timeSpan=
      AixLib.BoundaryConditions.WeatherData.BaseClasses.getTimeSpanTMY3(filNam,
      "tab1") "Start time, end time of weather data";

initial equation
  assert(abs(timeSpan[2]-14400) < 0.1, "Error in getting time span.");
end GetTimeSpanTMY3LongHeader;


Test model to get time span of a weather file, start time is non zero. This example tests getting time span of a TMY3 weather data file that
starts at a non-zero time.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model GetTimeSpanTMY3_NonzeroStart
  "Test model to get time span of a weather file, start time is non zero"
  extends Modelica.Icons.Example;
  extends AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples.GetTimeSpanTMY3(
    filNam = Modelica.Utilities.Files.loadResource(
 "modelica://AixLib/Resources/Data/BoundaryConditions/WeatherData/Validation/DecemberToJanuary.mos"),
    staTim = 30992400,
    endTim = 31863600);
end GetTimeSpanTMY3_NonzeroStart;


Test model for ceiling height check. This example tests the model that constrains the ceiling height.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model LimitMin "Test model for ceiling height check"
  extends Modelica.Icons.Example;
  AixLib.Utilities.Time.ModelTime modTim
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LimiterCeilingHeight limCeiHei
    "Block that constrains the ceiling height"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.ConvertTime conTim(
    weaDatStaTim=0,
    weaDatEndTim=31536000)
    "Block that converts time"
protected
  Modelica.Blocks.Tables.CombiTable1Ds datRea(
    tableOnFile=true,
    tableName="tab1",
    fileName=Modelica.Utilities.Files.loadResource(
       Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")),
    columns=2:30,
    smoothness=Modelica.Blocks.Types.Smoothness.ContinuousDerivative)
    "Data reader"
equation
  connect(datRea.y[20],limCeiHei.u)
  connect(modTim.y, conTim.modTim)
  connect(conTim.calTim, datRea.u)
end LimitMin;


Test model for calculate local civil time. This example tests the model that computes the local civil time.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model LocalCivilTime "Test model for calculate local civil time"
  extends Modelica.Icons.Example;
  AixLib.Utilities.Time.ModelTime modTim
    "Block that outputs the model time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LocalCivilTime locTim(
      timZon=-21600, lon=-1.5293932423067)
equation
  connect(modTim.y, locTim.cloTim)
end LocalCivilTime;


within AixLib.BoundaryConditions.WeatherData.BaseClasses;
package Examples "Collection of models that illustrate model use and test models"
extends Modelica.Icons.ExamplesPackage;
end Examples;


Test model for solar time. This example tests the model that computes the solar time.

within AixLib.BoundaryConditions.WeatherData.BaseClasses.Examples;
model SolarTime "Test model for solar time"
  extends Modelica.Icons.Example;
  Utilities.Time.ModelTime modTim "Block that outputs simulation time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.LocalCivilTime locTim(
      timZon=-21600,
      lon=-1.7039261675061) "Block that computes the local civil time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.SolarTime solTim
    "Block that computes the solar time"
  AixLib.BoundaryConditions.WeatherData.BaseClasses.EquationOfTime eqnTim
    "Block that computes the equation of time"
equation
  connect(modTim.y, locTim.cloTim)
  connect(locTim.locTim, solTim.locTim)
  connect(modTim.y, eqnTim.nDay)
  connect(eqnTim.eqnTim, solTim.equTim)
end SolarTime;


within AixLib.BoundaryConditions.WeatherData;
package Examples "Collection of models that illustrate model use and test models"
  extends Modelica.Icons.ExamplesPackage;
end Examples;


Test model for reading weather data. This model tests the TMY3 data reader.
The instance weaDat obtains all weather data from the weather file,
whereas the instance weaDatInpCon obtains the global horizontal and
the diffuse horizontal solar radiation from its input connectors.

within AixLib.BoundaryConditions.WeatherData.Examples;
model ReaderTMY3 "Test model for reading weather data"
  extends Modelica.Icons.Example;
  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(
    filNam=Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"))
    "Weather data reader"
  AixLib.BoundaryConditions.WeatherData.ReaderTMY3 weaDatInpCon(filNam=
        Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos"),
      HSou=AixLib.BoundaryConditions.Types.RadiationDataSource.Input_HGloHor_HDifHor)
    "Weather data reader with radiation data obtained from input connector"
  Modelica.Blocks.Sources.Constant HDifHor(k=0) "Diffuse horizontal radiation"
  Modelica.Blocks.Sources.Constant HGloHor(k=0) "Horizontal global radiation"
equation
  connect(HGloHor.y, weaDatInpCon.HGloHor_in)
  connect(HDifHor.y, weaDatInpCon.HDifHor_in)
end ReaderTMY3;


within AixLib.BoundaryConditions.WeatherData;
package Old "Old weather data reader of AixLib for TRY data"
end Old;


Complex weather model.

within AixLib.BoundaryConditions.WeatherData.Old.WeatherTRY;
model Weather "Complex weather model"
  parameter Modelica.Units.NonSI.Angle_deg Latitude=49.5 "latitude of location"
  parameter Modelica.Units.NonSI.Angle_deg Longitude=8.5
    "longitude of location"
  parameter Modelica.Units.NonSI.Time_hour DiffWeatherDataTime=1
    "difference between weather data time and UTC, e.g. +1 for CET"
  parameter Real GroundReflection = 0.2 "ground reflection coefficient"
  parameter String tableName = "wetter"
    "table name on file or in function usertab"
  parameter String fileName = Modelica.Utilities.Files.loadResource("modelica://AixLib/Resources/weatherdata/TRY2010_12_Jahr_Modelica-Library.txt")
    "file where matrix is stored";Matlab files (*.mat)", caption = "Open file in which table is present")));
  parameter String formatTRY="TRY 2010/2011" "File format of test reference year (TRY)"
  parameter Real offset[:] = {0} "offsets of output signals"
  parameter Modelica.Blocks.Types.Smoothness smoothness = Modelica.Blocks.Types.Smoothness.LinearSegments
    "Smoothness of table interpolation"
  parameter Modelica.Blocks.Types.Extrapolation extrapolation = Modelica.Blocks.Types.Extrapolation.Periodic
    "Extrapolation of data outside the definition range"
  parameter Real startTime[1] = {0}
    "output = offset for time < startTime (same value for all columns)"

  replaceable model RadOnTiltedSurface =
      AixLib.BoundaryConditions.WeatherData.Old.WeatherTRY.RadiationOnTiltedSurface.RadOnTiltedSurf_Liu
    constrainedby
    AixLib.BoundaryConditions.WeatherData.Old.WeatherTRY.RadiationOnTiltedSurface.BaseClasses.PartialRadOnTiltedSurf
    "Model for calculating radiation on tilted surfaces"

  parameter
    DataBase.Weather.SurfaceOrientation.SurfaceOrientationBaseDataDefinition         SOD = DataBase.Weather.SurfaceOrientation.SurfaceOrientationData_N_E_S_W_Hor()
    "Surface orientation data"
  Utilities.Interfaces.SolarRad_out SolarRadiation_OrientedSurfaces[SOD.nSurfaces]
  parameter Boolean outOpt = true "Output individual vectors instead of one vector [-]"
  parameter Boolean Cloud_cover = false "Cloud cover [-] (TRY col 7)"
  parameter Boolean Wind_dir = false "Wind direction [deg] (TRY col 8)"
  parameter Boolean Wind_speed = false "Wind speed [m/s]  (TRY col 9)"
  parameter Boolean Air_temp = false "Air temperature [K] (TRY col 10)"
  parameter Boolean Air_press = false "Air pressure [Pa] (TRY col 11)"
  parameter Boolean Mass_frac = false
    "Mass fraction of water in dry air [kg/kg] (TRY col 12)"
  parameter Boolean Rel_hum = false "Realtive humidity of air [-] (TRY col 13)"
  parameter Boolean Sky_rad = false
    "Longwave sky radiation on horizontal [W/m2] (TRY col 18)"
  parameter Boolean Ter_rad = false
    "Longwave terrestric radiation from horizontal [W/m2] (TRY col 19)"
  BaseClasses.Sun Sun(
    Longitude=Longitude,
    Latitude=Latitude,
    DiffWeatherDataTime=DiffWeatherDataTime)
  RadOnTiltedSurface RadOnTiltedSurf[SOD.nSurfaces](each Latitude = Latitude, each GroundReflection = GroundReflection, Azimut = SOD.Azimut, Tilt = SOD.Tilt, each WeatherFormat=false)
  Modelica.Blocks.Sources.CombiTimeTable WeatherData(fileName = Modelica.Utilities.Files.loadResource(fileName), columns = columns, offset = offset, table = [0, 0; 1, 1], startTime = scalar(startTime), tableName = tableName, tableOnFile = tableName <> "NoName", smoothness = smoothness, extrapolation = extrapolation)
  Modelica.Blocks.Routing.DeMultiplex3 deMultiplex(n3 = 9)
  Modelica.Blocks.Interfaces.RealOutput WeatherDataVector[m] if outOpt == false and (Cloud_cover or Wind_dir or Wind_speed or Air_temp or Air_press or Mass_frac or Rel_hum or Sky_rad or Ter_rad)
  Modelica.Blocks.Interfaces.RealOutput CloudCover if Cloud_cover and outOpt "[0..8]"
  Modelica.Blocks.Interfaces.RealOutput WindDirection(unit = "deg") if Wind_dir and outOpt
    "in deg [0...360]"
  Modelica.Blocks.Interfaces.RealOutput WindSpeed(unit = "m/s") if Wind_speed and outOpt "in m/s"
  Modelica.Blocks.Interfaces.RealOutput AirTemp(unit = "K") if Air_temp and outOpt
    "in Kelvin"
  Modelica.Blocks.Interfaces.RealOutput AirPressure(unit = "Pa") if Air_press and outOpt "in Pa"
  Modelica.Blocks.Interfaces.RealOutput WaterInAir if Mass_frac and outOpt
    "in kg/kg"
  Modelica.Blocks.Interfaces.RealOutput RelHumidity if Rel_hum and outOpt
    "in percent"
  Modelica.Blocks.Interfaces.RealOutput SkyRadiation(unit = "W/m2") if Sky_rad and outOpt "in W/m2"
  Modelica.Blocks.Interfaces.RealOutput TerrestrialRadiation(unit = "W/m2") if Ter_rad and outOpt "in W/m2"
  Modelica.Blocks.Math.Gain hPa_to_Pa(k = 100) if Air_press
  Modelica.Blocks.Math.Gain percent_to_unit(k = 0.01) if Rel_hum
  Modelica.Blocks.Math.Gain g_to_kg(k = 0.001) if Mass_frac
  Modelica.Blocks.Math.UnitConversions.From_degC from_degC if Air_temp
protected
  parameter Integer m = BaseClasses.CalculateNrOfOutputs(Cloud_cover, Wind_dir, Wind_speed, Air_temp, Air_press, Mass_frac, Rel_hum, Sky_rad, Ter_rad)
    "Number of chosen output variables";
  parameter Integer[9] PosWV = BaseClasses.DeterminePositionsInWeatherVector(Cloud_cover, Wind_dir, Wind_speed, Air_temp, Air_press, Mass_frac, Rel_hum, Sky_rad, Ter_rad)
    "Positions Weather Vector";
  /*
  | 1: year / Modelica time | 2         | 3         | 4         | 5         | 6         | 7         | 8         | 9         | 10        | 11        | 12        | 13         | 14        | 15        | 16        | 17        | 18        | 19       | 20       |
  | 2010/2011               | RG        | IS        | MM        | DD        | HH        | N         | WR        | WG        | t         | p         | x         | RF         | W         | B         | D         | IK        | A         | E        | IL       |
  | 2015/2017               | RW        | HW        | MM        | DD        | HH        | t         | p         | WR        | WG        | N         | x         | RF         | B         | D         | A         | E         | IL        |          |          |
  */
  parameter Integer columns[:] = if formatTRY=="TRY 2015/2017" then {15, 14, 11, 9, 10, 7, 8, 12, 13, 16, 17} elseif formatTRY=="TRY 2010/2011" then {16, 15, 7, 8, 9, 10, 11, 12, 13, 18, 19} else fill(0, 11);
initial equation
  assert(SOD.nSurfaces == size(SOD.name, 1), "name has to have the nSurfaces Elements (see Surface orientation data in the Weather Model)");
  assert(SOD.nSurfaces == size(SOD.Azimut, 1), "Azimut has to have the nSurfaces Elements (see Surface orientation data in the Weather Model)");
  assert(SOD.nSurfaces == size(SOD.Tilt, 1), "Tilt has to have the nSurfaces Elements (see Surface orientation data in the Weather Model)");
equation
  // cloud cover
  if Cloud_cover then
    if outOpt == false then
      connect(WeatherDataVector[PosWV[1]], deMultiplex.y3[1]);
    else
      connect(CloudCover, deMultiplex.y3[1]);
    end if;
  end if;
  // wind direction
  if Wind_dir then
    if not outOpt then
      connect(WeatherDataVector[PosWV[2]], deMultiplex.y3[2]);
    else
      connect(WindDirection, deMultiplex.y3[2]);
    end if;
  end if;
  // wind speed
  if Wind_speed then
    if not outOpt then
      connect(WeatherDataVector[PosWV[3]], deMultiplex.y3[3]);
    else
      connect(WindSpeed, deMultiplex.y3[3]);
    end if;
  end if;
  // air temperature
  if Air_temp then
    if not outOpt then
      connect(deMultiplex.y3[4], from_degC.u);
      connect(WeatherDataVector[PosWV[4]], from_degC.y);
    else
      connect(deMultiplex.y3[4], from_degC.u);
      connect(AirTemp, from_degC.y);
    end if;
  end if;
  // air pressure, conversion from hPa to Pa
  if Air_press then
    if not outOpt then
      connect(deMultiplex.y3[5], hPa_to_Pa.u);
      connect(WeatherDataVector[PosWV[5]], hPa_to_Pa.y);
    else
      connect(deMultiplex.y3[5], hPa_to_Pa.u);
      connect(AirPressure, hPa_to_Pa.y);
    end if;
  end if;
  // mass fraction water in dry air, conversion from g/kg to kg/kg
  if Mass_frac then
    if not outOpt then
      connect(deMultiplex.y3[6], g_to_kg.u);
      connect(WeatherDataVector[PosWV[6]], g_to_kg.y);
    else
      connect(deMultiplex.y3[6], g_to_kg.u);
      connect(WaterInAir, g_to_kg.y);
    end if;
  end if;
  // rel. humidity, conversion from % to 0..1
  if Rel_hum then
    if not outOpt then
      connect(deMultiplex.y3[7], percent_to_unit.u);
      connect(WeatherDataVector[PosWV[7]], percent_to_unit.y);
    else
      connect(deMultiplex.y3[7], percent_to_unit.u);
      connect(RelHumidity, percent_to_unit.y);
    end if;
  end if;
  // longwave sky radiation
  if Sky_rad then
    if not outOpt then
      connect(WeatherDataVector[PosWV[8]], deMultiplex.y3[8]);
    else
      connect(SkyRadiation, deMultiplex.y3[8]);
    end if;
  end if;
  // longwave terrestric radiation
  if Ter_rad then
    if not outOpt then
      connect(WeatherDataVector[PosWV[9]], deMultiplex.y3[9]);
    else
      connect(TerrestrialRadiation, deMultiplex.y3[9]);
    end if;
  end if;
  connect(WeatherData.y, deMultiplex.u)
 // Connecting n RadOnTiltedSurf
  for i in 1:SOD.nSurfaces loop
    connect(Sun.OutDayAngleSun, RadOnTiltedSurf[i].InDayAngleSun);
    connect(Sun.OutHourAngleSun, RadOnTiltedSurf[i].InHourAngleSun);
    connect(Sun.OutDeclinationSun, RadOnTiltedSurf[i].InDeclinationSun);
    connect(deMultiplex.y1[1], RadOnTiltedSurf[i].solarInput2);
    connect(deMultiplex.y2[1], RadOnTiltedSurf[i].solarInput1);
  end for;

  connect(RadOnTiltedSurf.OutTotalRadTilted, SolarRadiation_OrientedSurfaces)
end Weather;


Computes the sun's altitude of the current site.

within AixLib.BoundaryConditions.WeatherData.Old.WeatherTRY.BaseClasses;
model Sun "Computes the sun's altitude of the current site"

import Modelica.Units.Conversions.from_deg;
import Modelica.Units.Conversions.to_deg;
  parameter Real TimeCorrection = 0.5 "for TRY = 0.5, for TMY = 0";
  parameter Modelica.Units.NonSI.Angle_deg Latitude "latitude of location";
  parameter Modelica.Units.NonSI.Angle_deg Longitude "longitude of location in";
  parameter Modelica.Units.NonSI.Time_hour DiffWeatherDataTime
    "difference between local time and UTC, e.g. +1 for MET";
  parameter Real Diff_localStandardTime_WeatherDataTime = 0
    "difference between weather data time and the time of the local time zone";

  Real NumberOfDay;
  Real SolarTime;
  Real TimeEquation;
  Modelica.Blocks.Interfaces.RealOutput OutHourAngleSun
  Modelica.Blocks.Interfaces.RealOutput OutDeclinationSun
  Modelica.Blocks.Interfaces.RealOutput OutDayAngleSun

  Real DeclinationSun;
  Real HourAngleSun;
  Real DayAngleSun;
  Real StandardTime "the time of the standard time zone of the WeatherData";
equation
//calculation of the SolarTime (Duffie2006 chap. 1.5)

      // number of day: 1 = Jan 1st
      NumberOfDay = time/86400 + 1
    "NumberOfDay is calculated as float because then the variables that use NumberoOfDay in their calculation don't have to be interpolated between the time-steps. To get the integer value it has to be calculated with: NumberOfDay =floor(time/86400) + 1";

      // day angle of sun
      DayAngleSun = 360/365.25*(NumberOfDay - 1)
    "360 is an angle in degree and 365 is the number of days in one year. The earth rotation in one year is 360 degrees";

      OutDayAngleSun = DayAngleSun;

      // equation of time in hours - used to convert local time in solar time
      TimeEquation = 229.2*(0.000075+0.001868*cos(from_deg(DayAngleSun))-0.032077*sin(from_deg(DayAngleSun))-0.014615*cos(2*from_deg(DayAngleSun))-0.04089*sin(2*from_deg(DayAngleSun)))/60;
      StandardTime=mod(time/3600, 24);
      SolarTime =  StandardTime - TimeCorrection - (DiffWeatherDataTime + Diff_localStandardTime_WeatherDataTime) + 4 * (Longitude)/60 + TimeEquation
    "the difference between the UTC and the time standard is given by DiffWeatherDataTime and Diff_lokalStandardTime Longitude";

// hour angle of sun, first term calculates local time of day from continuous time signal
      HourAngleSun = (SolarTime-12) * 360/24 "HourAngleSun=0 deg means sun peak";
      if (HourAngleSun > 180) then
        OutHourAngleSun = HourAngleSun - 360;
      elseif (HourAngleSun < -180) then
        OutHourAngleSun = HourAngleSun + 360;
      else
        OutHourAngleSun = HourAngleSun;
      end if;

// declination of sun
      DeclinationSun = (to_deg(0.006918 - 0.399912 * cos(from_deg(DayAngleSun)) + 0.070257 * sin(from_deg(DayAngleSun)) - 0.006758 * cos(2*from_deg(DayAngleSun)) + 0.000907 * sin(2*from_deg(DayAngleSun)) - 0.002679 * cos(3*from_deg(DayAngleSun)) + 0.00148 * sin(3*from_deg(DayAngleSun))));
      OutDeclinationSun=DeclinationSun;
end Sun;


Lsodar.

within AixLib.BoundaryConditions.WeatherData.Old.WeatherTRY.Examples;
model WeatherModels
  extends Modelica.Icons.Example;
  BoundaryConditions.WeatherData.Old.WeatherTRY.Weather weather(
    Cloud_cover=true,
    Wind_dir=true,
    Wind_speed=true,
    Air_temp=true,
    Air_press=true,
    Mass_frac=true,
    Rel_hum=true,
    Sky_rad=true,
    Ter_rad=true)
equation
end WeatherModels;


Calculates solar radiation on tilted surfaces according to Liu.

within AixLib.BoundaryConditions.WeatherData.Old.WeatherTRY.RadiationOnTiltedSurface;
model RadOnTiltedSurf_Liu
  "Calculates solar radiation on tilted surfaces according to Liu"
  extends BaseClasses.PartialRadOnTiltedSurf;

import Modelica.Units.Conversions.from_deg;

  Real InBeamRadHor "beam irradiance on the horizontal surface";
  Real InDiffRadHor "diffuse irradiance on the horizontal surface";

  Real cos_theta;
  Real cos_theta_help;
  Real cos_theta_z;
  Real cos_theta_z_help;
  Real R;
  Real R_help;
  Real term;

equation
  // calculation of cos_theta_z [Duffie/Beckman, p.15], cos_theta_z is manually cut at 0 (no neg. values)
  cos_theta_z_help = sin(from_deg(InDeclinationSun))*sin(from_deg(
    Latitude)) + cos(from_deg(InDeclinationSun))*cos(from_deg(Latitude))*
    cos(from_deg(InHourAngleSun));
  cos_theta_z = (cos_theta_z_help + abs(cos_theta_z_help))/2;

  // calculation of cos_theta [Duffie/Beckman, p.15], cos_theta is manually cut at 0 (no neg. values)
  term = cos(from_deg(InDeclinationSun))*sin(from_deg(Tilt))*sin(from_deg(
    Azimut))*sin(from_deg(InHourAngleSun));
  cos_theta_help = sin(from_deg(InDeclinationSun))*sin(from_deg(Latitude))
    *cos(from_deg(Tilt)) - sin(from_deg(InDeclinationSun))*cos(from_deg(
    Latitude))*sin(from_deg(Tilt))*cos(from_deg(Azimut)) + cos(from_deg(
    InDeclinationSun))*cos(from_deg(Latitude))*cos(from_deg(Tilt))*cos(
    from_deg(InHourAngleSun)) + cos(from_deg(InDeclinationSun))*sin(
    from_deg(Latitude))*sin(from_deg(Tilt))*cos(from_deg(Azimut))*cos(
    from_deg(InHourAngleSun)) + term;
  cos_theta = (cos_theta_help + abs(cos_theta_help))/2;

  // calculation of R factor [Duffie/Beckman, p.25], due to numerical problems (cos_theta_z in denominator)
  // R is manually set to 0 for theta_z >= 80 deg (-> 90 deg means sunset)
  if noEvent(cos_theta_z <= 0.17365) then
    R_help = cos_theta_z*cos_theta;

  else
    R_help = cos_theta/cos_theta_z;

  end if;

  R = R_help;

  // conversion of direct and diffuse horizontal radiation
  if not WeatherFormat then // TRY
    InBeamRadHor = solarInput1;
    InDiffRadHor = solarInput2;
  else  // WeatherFormat == true , TMY then
    InBeamRadHor = solarInput1 * cos_theta_z;
    InDiffRadHor = max(solarInput2-InBeamRadHor, 0);
  end if;

  // calculation of total radiation on tilted surface according to model of Liu and Jordan
  // according to [Dissertation Nytsch-Geusen, p.98]
  OutTotalRadTilted.I = max(0, R*InBeamRadHor + 0.5*(1 + cos(from_deg(
    Tilt)))*InDiffRadHor + GroundReflection*(InBeamRadHor + InDiffRadHor)
    *((1 - cos(from_deg(Tilt)))/2));

  // Setting the outputs of direct. diffuse and ground reflection radiation on tilted surface and the angle of incidence
  OutTotalRadTilted.I_dir = R*InBeamRadHor;
  OutTotalRadTilted.I_diff = 0.5*(1 + cos(from_deg(Tilt)))*InDiffRadHor;
  OutTotalRadTilted.I_gr = GroundReflection*(InBeamRadHor + InDiffRadHor)*((1 - cos(from_deg(Tilt)))/2);

  OutTotalRadTilted.AOI = Modelica.Math.acos(cos_theta); // in rad
end RadOnTiltedSurf_Liu;