[TestMethod]
public async Task InputAvg()
{
// dp, sp, temp, base density and flowing density use the same class, so this covers all of those use cases
TestScript script = Flow.GetAerTestCase01_UpstreamTap();
script.RunTime = new TimeSpan(56, 0, 0);
script.StartTime = DateTime.UtcNow;
int secondsOffset = 60 - script.StartTime.Second;
int minuteOffset = 59 - script.StartTime.Minute; // time to the end of the current hour. minute offset may be 0!
int offsetHr = secondsOffset + minuteOffset * 60;
// this is the contract time tomorrow
DateTime contractTs = new DateTime(script.StartTime.Year, script.StartTime.Month, script.StartTime.Day, 8, 0, 0).AddDays(1.0d);
// totalOffset is the time to the next contract day in seconds
int offsetDy = Convert.ToInt32(Math.Truncate(contractTs.Subtract(script.StartTime).TotalSeconds)) + 1;
if(offsetDy > 86400)
{
offsetDy -= 86400;
}
Console.WriteLine($"Time is {script.StartTime}, seconds offset is {secondsOffset}, minute offset is {minuteOffset}, hour offset is {offsetHr}, day offset {offsetDy}");
// user defined values. These have to happen after the app is initialized
script.Changes.Add(1, new List());
script.Changes[1].Add(new TestChange((int)GasFlow_001_005.ParametersEnum.spTag, 2818.09d)); // kPa
script.Changes[1].Add(new TestChange((int)GasFlow_001_005.ParametersEnum.dpTag, 102.0d)); // millibar
script.Changes[1].Add(new TestChange((int)GasFlow_001_005.ParametersEnum.tempTag, 57.0d)); // C
// change logging level
script.Changes[1].Add(new TestChange((int)AppBase_v1.AppBaseParameterIds.logLevel, (object)3));
Random r = new Random();
double dp = 102.0d;
int dpMnCount = 0;
double dpMnSum = 0.0d;
double dpMnAvg = 0.0d;
int dpHrCount = 0;
double dpHrSum = 0.0d;
double dpHrAvg = 0.0;
int dpDyCount = 0;
double dpDySum = 0.0d;
double dpDyAvg = 0.0d;
double dpHrAvg_ = 0.0d;
double dpDyAvg_ = 0.0d;
for(int i = 2; i < script.RunTime.TotalSeconds; i++)
{
if(r.NextDouble() >= 0.90)
{
// change input values when a randomly generated number is above some threshold
// this prevents the dp from changing very second.
// the dp actually changes in the next second, so do averaging first when a change is coming
dpMnSum += dp;
dpMnCount++;
dpMnAvg = dpMnSum / dpMnCount;
// change the value
dp = (r.NextDouble() * 100.0d) + 10.0d; // between 10 and 110;
if(script.Changes.ContainsKey(i) == false)
{
script.Changes.Add(i, new List());
}
script.Changes[i].Add(new TestChange((int)GasFlow_001_005.ParametersEnum.dpTag, dp)); // millibar
}
else
{
// the value didn't change, just track the sum and count
dpMnSum += dp;
dpMnCount++;
dpMnAvg = dpMnSum / dpMnCount;
}
if(i >= secondsOffset)
{
if((i - secondsOffset) % 60 == 0)
{
// on a minute boundary
// verify that the minute average from the app matches our calculated value.
// If the assert is not true then the test will stop
if (script.Asserts.ContainsKey(i) == false)
{
script.Asserts.Add(i, new List());
}
script.Asserts[i].Add(new TestAssert(AssertTypes.areEqual, (int)GasFlow_001_005.ParametersEnum.mnDpAvg, dpMnAvg, 0.0001));
// increment hour values when a new minute occurs
// get a weighted average
dpHrSum += dpMnAvg * dpMnCount;
dpHrCount += dpMnCount;
dpHrAvg = dpHrSum / dpHrCount;
// reset minute values
dpMnSum = 0;
dpMnCount = 0;
}
}
if(i >= offsetHr)
{
if ((i - offsetHr) % 3600 == 0)
{
// on an hour boundary
// verify that the hour average matches our our calculated value
// If the assert is not true then the test will stop
if (script.Asserts.ContainsKey(i) == false)
{
script.Asserts.Add(i, new List());
}
script.Asserts[i].Add(new TestAssert(AssertTypes.areEqual, (int)GasFlow_001_005.ParametersEnum.hrDpAvg, dpHrAvg, 0.0001));
// increment day values when a new hour occurs
dpDySum += dpHrAvg * dpHrCount;
dpDyCount += dpHrCount;
dpDyAvg = dpDySum / dpDyCount;
// reset hour values
dpHrCount = 0;
dpHrSum = 0;
}
}
if(i >= offsetDy)
{
if((i - offsetDy) % 86400 == 0)
{
// on a day boundary
// verify that the day average matches our calculated vaulue.
// If the assert is not true then the test will stop
if (script.Asserts.ContainsKey(i) == false)
{
script.Asserts.Add(i, new List());
}
script.Asserts[i].Add(new TestAssert(AssertTypes.areEqual, (int)GasFlow_001_005.ParametersEnum.dyDpAvg, dpDyAvg, 0.0001));
// reset day value
dpDyCount = 0;
dpDySum = 0;
}
}
if(dpMnCount == 0 && dpHrCount == 0)
{
// cut loop short for the first time through
continue;
}
if(r.NextDouble() < 0.02)
{
// If a randomly generated value is less that some amount,
// update day and hour as required, not just on boundaries
dpHrAvg_ = ((dpMnAvg * dpMnCount) + (dpHrAvg * dpHrCount)) / (dpMnCount + dpHrCount);
dpDyAvg_ = ((dpMnAvg * dpMnCount) + (dpHrAvg * dpHrCount) + (dpDyAvg * dpDyCount)) / (dpMnCount + dpHrCount + dpDyCount);
// Assert that values are correct
if (script.Asserts.ContainsKey(i) == false)
{
script.Asserts.Add(i, new List());
}
script.Asserts[i].Add(new TestAssert(AssertTypes.areEqual, (int)GasFlow_001_005.ParametersEnum.mnDpAvg, dpMnAvg, 0.0001));
script.Asserts[i].Add(new TestAssert(AssertTypes.areEqual, (int)GasFlow_001_005.ParametersEnum.hrDpAvg, dpHrAvg_, 0.0001));
script.Asserts[i].Add(new TestAssert(AssertTypes.areEqual, (int)GasFlow_001_005.ParametersEnum.dyDpAvg, dpDyAvg_, 0.0001));
}
}
// execute the test script
AppRunBase_ runtime = await AppSpecificTestHelpers.ExecuteScript(script);
}