third commit

This commit is contained in:
Wesley Hofman
2025-09-18 14:36:50 +02:00
parent 633885bab9
commit 1232ca80c6
156 changed files with 724100 additions and 0 deletions

View File

@@ -0,0 +1,554 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Maser.Feanor.Model;
using Maser.Feanor.Biz;
using System.IO;
using System.Globalization;
namespace FeanorProjects
{
public static class Export
{
private static StringBuilder _Content; // File content
private static List<List<Result>> _Results = new List<List<Result>>();
public static void Create(Project Project, Chamber Chamber)
{
_Project = Project;
_Chamber = Chamber;
_Sensors = new List<Sensor>();
_File = "";
// Set project stop to UTC for current object
_Project.Stop = _Project.Stop == null ? Time.UTC : (DateTime)_Project.Stop;
}
public static List<Sensor> Sensors
{
get { return _Sensors; }
set { _Sensors = value; }
}
private static List<Sensor> _Sensors = new List<Sensor>();
public static Project Project { get { return _Project; } }
private static Project _Project;
public static Chamber Chamber { get { return _Chamber; } }
private static Chamber _Chamber;
public static String File { get { return _File; } set { _File = value; } }
private static String _File;
public static Boolean ToFile()
{
try
{
GetResults();
}
catch(Exception ex)
{
string msg = "Exception in Export.ToFile() during GetResults() -> " + ex.Message;
throw new Exception(msg);
}
_Content = new StringBuilder();
_Content.AppendLine(ProjectHeader);
_Content.AppendLine(ChamberHeader);
_Content.AppendLine(SensorHeader);
_Content.AppendLine(UncertaintyHeader);
AppendDataField();
_Content.AppendLine(FileStamp);
// Write the file
try
{
FileStream fileStream = new FileStream(_File, FileMode.Create);
StreamWriter MyStreamWriter = new StreamWriter(fileStream);
MyStreamWriter.WriteLine(_Content);
MyStreamWriter.Close();
fileStream.Close();
return true;
}
catch (Exception ex)
{
string msg = "Exception in Export.ToFile() during writing of file -> " + ex.Message;
throw new Exception(msg);
}
}
private static void AppendDataField()
{
List<ExportDataItem> exportDataItems = new List<ExportDataItem>();
String[,] dataField = new String[_Results[0].Count, _Sensors.Count + 1];
DateTime start = _Results[0][0].TimeStamp;
// sensor0 primary sensor (with timestamp)
for (int i = 1; i < _Sensors.Count; i++) //sensor1,sensor2,.... (without timestamp)
{
Sensor sensor = _Sensors[i];
List<Result> results = _Results[i];
}
int count = 0;
TimeSpan maxDifference = new TimeSpan(0, 0, 20); // max difference in time from sensor 0 timestamp
TimeSpan minDifference = new TimeSpan(0, 0, -20); // min difference in time from sensor 0 timestamp
//Console.WriteLine("count 0 and 1 "+ _Results[0].Count.ToString() + " " +_Results[2].Count.ToString());
//foreach (Result r in _Results[2]) // Itereer door elke rij van de eerste sensor
//Console.WriteLine("v ch1 " + r.TimeStamp.ToString() + " | " + r.Value.ToString());
Int32 foundsensorpk = 0;
double[] CalibrCoeff = new double[40];
for (int i = 0; i < _Sensors.Count; i++)
{
try
{
List<Int32> calibrationPKs = new List<int>();
foreach (Result r in _Results[i])
{
if (!calibrationPKs.Contains(r.CalibrationPK))
{
calibrationPKs.Add(r.CalibrationPK);
foundsensorpk = r.SensorPK;
}
}
Calibration t = new Calibrations().GetLastCreatedBySensorPK(foundsensorpk);
if (t != null) // calibration found
{
CalibrCoeff[2*i] = t.Coefficients[1]; // gain
CalibrCoeff[2*i+1] = t.Coefficients[0]; // offset
}
else // no calibration found
{
CalibrCoeff[2 * i] = 1.0; // gain
CalibrCoeff[2 * i + 1] = 0.0; // offset
}
}
catch
{
string msg = "Could not retrieve calibrations for sensor ";
}
}
int[] shift = new int[_Sensors.Count];
int[] skipcount = new int[_Sensors.Count];
#region oldExportSorter
/*
// Primary sensor is sensor with lowest ID (the first object in _Sensors)
foreach (Result r in _Results[0]) // for each row (first sensor)
{
ExportDataItem item = new ExportDataItem(r.TimeStamp, (r.Value*CalibrCoeff[0]+CalibrCoeff[1]), _Results.Count, start); // for sensor 0 export value and timestamp first sensor
exportDataItems.Add(item);
Console.Write(r.TimeStamp.ToString() + " " + r.Value.ToString() + " ");
for (int i = 1; i < _Sensors.Count; i++) // for the sensor1, sensor2, ....
{
try
{
TimeSpan difference = r.TimeStamp - _Results[i][count-shift[i]].TimeStamp; // Calculate difference between sensor 0 and sensor X
Console.Write(difference.TotalSeconds.ToString() + " ");
if (difference <= maxDifference && difference >= minDifference) // If difference is between min and max
{
// difference between sensor0 and sensor X is between max and min difference --> ADD value to file
}
else
{
// difference between sensor0 and sensor X is not between max and min difference --> DO NOT ADD VALUE to file
shift[i]++;
}
if (_Results[i][count - shift[i]].Value == 9999.99)
{
item.AddValue(_Results[i][count-shift[i]].Value, i);
}
else
{
_Results[i][count - shift[i]].Value = _Results[i][count-shift[i]].Value * CalibrCoeff[2*i] + CalibrCoeff[2*i+1];
item.AddValue(_Results[i][count-shift[i]].Value, i);
}
Console.Write(_Results[i][count - shift[i]].Value.ToString() + " ");
}
catch { }
}
count++; // next row
Console.WriteLine();
}
*/
#endregion
bool debug = true;
foreach (Result r in _Results[0])
{
//Console.WriteLine("timestamp "+ r.TimeStamp.ToString());
ExportDataItem item = new ExportDataItem(
r.TimeStamp,
(r.Value * CalibrCoeff[0] + CalibrCoeff[1]),
_Results.Count,
start
);
exportDataItems.Add(item);
for (int i = 1; i < _Sensors.Count; i++) // Itereren over andere sensoren (o.a. sensor 2)
{
bool dataAdded = false;
int index = BinarySearchClosestTimestamp(_Results[i], r.TimeStamp);
if (index != -1)
{
TimeSpan diff = _Results[i][index].TimeStamp - r.TimeStamp;
if (diff <= maxDifference && diff >= minDifference)
{
double calibratedValue = (_Results[i][index].Value != 9999.99)
? _Results[i][index].Value * CalibrCoeff[2 * i] + CalibrCoeff[2 * i + 1]
: _Results[i][index].Value;
item.AddValue(calibratedValue, i);
dataAdded = true;
}
}
// Voeg 0 toe als er geen match was
if (!dataAdded)
{
item.AddValue(0.0, i);
}
}
}
foreach (ExportDataItem exportDataItem in exportDataItems) // for each line of .csv file
{
_Content.AppendLine(exportDataItem.ToString()); // add line to content
}
}
private static int BinarySearchClosestTimestamp(List<Result> results, DateTime targetTimestamp)
{
int left = 0, right = results.Count - 1;
while (left <= right)
{
int mid = left + (right - left) / 2;
if (results[mid].TimeStamp == targetTimestamp)
return mid;
else if (results[mid].TimeStamp < targetTimestamp)
left = mid + 1;
else
right = mid - 1;
}
int closestIndex = Math.Max(0, Math.Min(left, results.Count - 1));
return closestIndex;
}
private static void GetResults()
{
_Results = new List<List<Result>>();
foreach (Sensor sensor in _Sensors)
{
if(Chamber.Humidity == true)
{
_Results.Add(new Results().GetByProjectWindow(_Project.PK, sensor.PK));
}
else
{
_Results.Add(new Results().GetByProjectWindowOudeHal(_Project.PK, sensor.PK));
}
}
}
private static string UncertaintyHeader
{
get
{
String uncertainty;
uncertainty = String.Format("Uncertainty (k=2), {0:0}, ", Math.Ceiling((double)_Chamber.Interval / 2));
double U = 0;
Int32 foundsensorpk = 0;
for (int i = 0; i < _Sensors.Count; i++)
{
try
{
List<Int32> calibrationPKs = new List<int>();
foreach (Result r in _Results[i])
{
if (!calibrationPKs.Contains(r.CalibrationPK))
{
//Console.WriteLine(r.SensorPK.ToString()); // 21 dit gaat goed
calibrationPKs.Add(r.CalibrationPK);
//Console.WriteLine(r.CalibrationPK.ToString());
foundsensorpk = r.SensorPK;
}
}
Console.Write("Found sensor PK = ");
Console.WriteLine(foundsensorpk.ToString());
Calibration t = new Calibrations().GetLastCreatedBySensorPK(foundsensorpk);
if (t != null) // calibration found
{
U = t.Uncertainty;
Console.Write("a = ");
Console.Write(t.Coefficients[1]); // gain
Console.Write(" ");
Console.Write("b = ");
Console.WriteLine(t.Coefficients[0]); // offset
}
else // no calibration found
{
Console.WriteLine("No calibration found for this sensor ( a = 0 and b = 0 )");
U = 0.0;
}
}
catch
{
string msg = "Could not retrieve calibrations for sensor ";
msg += string.Format("PK={0:0} ChamberPK={1:0) ID={2:00} [{3}]", _Sensors[i].PK, _Sensors[i].ChamberPK, _Sensors[i].ID, _Sensors[i].Description);
throw new Exception(msg);
}
uncertainty += String.Format("{0:0.00},", U);
}
// Remove last comma of line
uncertainty = uncertainty.Remove(uncertainty.Length - 1, 1);
Console.WriteLine(uncertainty);
return uncertainty;
}
}
private static string SensorHeader
{
get
{
String sensorHeader;
// Are sensors from other chambers linked to project's chamber?
bool linked = false;
foreach (Sensor sensor in _Sensors)
{
if (sensor.ChamberPK != _Chamber.PK)
{
linked = true;
break;
}
}
sensorHeader = "Timestamp, Duration,";
foreach (Sensor sensor in _Sensors)
{
if(linked)
{
try
{
Chamber c = new Chambers().GetByPK(sensor.ChamberPK);
sensorHeader = string.Format("{0:00000}.{1:00} {2}", c.MIDS, sensor.ID, sensor.Description);
}
catch { sensorHeader += String.Format("\"#{0:00} {1}\",", sensor.ID, sensor.Description); }
}
else
sensorHeader += String.Format("\"#{0:00} {1}\",", sensor.ID, sensor.Description);
}
// Remove last comma of line
sensorHeader = sensorHeader.Remove(sensorHeader.Length - 1, 1);
// Add newline
sensorHeader += "\n";
// Units
sensorHeader += "YYYY/MM/DD @ hh:mm:ss, s,";
foreach (Sensor sensor in _Sensors)
sensorHeader += String.Format("{0},", sensor.Units);
// Remove last comma of line
sensorHeader = sensorHeader.Remove(sensorHeader.Length - 1, 1);
return sensorHeader;
}
}
private static string ProjectHeader
{
get
{
DateTime stop = (DateTime)_Project.Stop; // Cast to non-nullable
string projectHeader;
projectHeader = "Project details\r\n";
projectHeader += String.Format(",Customer, \"{0}\"\r\n", _Project.Customer);
projectHeader += String.Format(",P{0:000000} , \"{1}\"\r\n", _Project.ProjectID, _Project.ProjectDescription);
projectHeader += String.Format(",Sub {0:00} , \"{1}\"\r\n", _Project.SubProject, _Project.SubProjectDescription);
String stepD = _Project.StepDescription;
stepD = stepD.Replace(System.Environment.NewLine, " ");
Console.WriteLine(stepD);
projectHeader += String.Format(",Step {0:00} , \"{1}\"\r\n", _Project.Step, stepD);
projectHeader += String.Format(",Start, {0:0000}/{1:00}/{2:00} @ {3:00}:{4:00}\r\n", _Project.Start.Year, _Project.Start.Month, _Project.Start.Day, _Project.Start.Hour+1, _Project.Start.Minute);
projectHeader += String.Format(",Stop, {0:0000}/{1:00}/{2:00} @ {3:00}:{4:00}\r\n", stop.Year, stop.Month, stop.Day, stop.Hour+1, stop.Minute);
projectHeader += "\r\n";
projectHeader += ",Note: Time is observed in Central European Time+1 (UTC+1).\r\n";
return projectHeader;
}
}
private static string ChamberHeader
{
get
{
// return String.Format("Apparatus, \"{0:00000} {1}\"\r\n", _Chamber.MIDS, _Chamber.Description);
return String.Format("Apparatus, \"{0:00000}\"\r\n", _Chamber.MIDSandDescription);
}
}
public static string FileStamp
{
get
{
string str = "Maser Engineering B.V. Central Monitoring System";
//return String.Format("\r\n{0}{1}{2} {3}", Time.UTC.Year, Time.UTC.Month, Time.UTC.Day, str); // <-- original \r\n zorgt voor witregel wat problemen met META geeft
return String.Format("{0}{1}{2} {3}", Time.UTC.Year, Time.UTC.Month, Time.UTC.Day, str);
}
}
public static string DefaultExportFileName
{
get
{
return String.Format("P{0:00000}-{1:00}-{2:00} measurements in {3:00000}.csv", _Project.ProjectID, _Project.SubProject, _Project.Step, _Chamber.MIDS);
}
}
}
public class ExportDataItem
{
public DateTime TimeStamp
{
get { return _timeStamp; }
}
private DateTime _timeStamp;
private Double[] _sensorData;
private DateTime _startOfProject;
public ExportDataItem(DateTime timeStamp, Double firstValue, Int32 sensorCount, DateTime startOfProject)
{
_timeStamp = timeStamp;
_sensorData = new Double[sensorCount];
_sensorData[0] = firstValue;
_startOfProject = startOfProject;
}
public void AddValue(Double value, Int32 SensorNr)
{
try
{
if (SensorNr < _sensorData.Length)
_sensorData[SensorNr] = value;
}
catch { }
}
public override string ToString()
{
StringBuilder result = new StringBuilder();
var culture = CultureInfo.InvariantCulture; // Zorgt ervoor dat het decimaalteken altijd een punt is.
// exported time is UTC + 1 !!!!
// onderstaande regel zorgde voor fouten rond middernacht data zoals 00h01 werd geexporteerd als 24h01
// result.AppendFormat("{0:0000}/{1:00}/{2:00} @ {3:00}:{4:00}:{5:00},", TimeStamp.Year, TimeStamp.Month, TimeStamp.Day, TimeStamp.Hour+1, TimeStamp.Minute, TimeStamp.Second);
DateTime localTime = TimeStamp.AddHours(1); // UTC +1 correct verwerken
result.AppendFormat("{0:0000}/{1:00}/{2:00} @ {3:00}:{4:00}:{5:00},",
localTime.Year, localTime.Month, localTime.Day,
localTime.Hour, localTime.Minute, localTime.Second);
result.AppendFormat("{0}", ((TimeSpan)TimeStamp.Subtract(_startOfProject)).TotalSeconds);
foreach (Double value in _sensorData)
{
if (Math.Abs(value) < 1 && value != 0)
{
int k = 0;
Double v = Math.Abs(value);
while (v < 10 && k < 10)
{
v = v * 10;
k++;
}
string s = ",{0:0.";
for (int i = 0; i < k; i++)
{
s += "0";
}
s += "000}";
result.AppendFormat(culture,s, value);
}
else
{
result.AppendFormat(culture,",{0:0.00}", value);
}
}
//Console.WriteLine(result.ToString());
return result.ToString();
}
}
}