init
This commit is contained in:
300
DataPRO/SensorDB/SensorMerge.cs
Normal file
300
DataPRO/SensorDB/SensorMerge.cs
Normal file
@@ -0,0 +1,300 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
using DTS.Slice.Users;
|
||||
|
||||
namespace DTS.SensorDB
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that handles merging of sensor calibrations
|
||||
/// </summary>
|
||||
public class SensorMerge
|
||||
{
|
||||
|
||||
public List<SensorData> SensorDataMergeList { get; private set; } = new List<SensorData>();
|
||||
public Dictionary<string, List<SensorCalibration>> SensorCalibrationMergeList { get; private set; } = new Dictionary<string, List<SensorCalibration>>();
|
||||
|
||||
public Dictionary<int, int> OldSensorDatabaseIdToNew { get; private set; } = new Dictionary<int, int>();
|
||||
private readonly User _currentUser = null;
|
||||
|
||||
private readonly object _lock = new object();
|
||||
private Dictionary<string, MergeStatus> _mergeStatuses = new Dictionary<string, MergeStatus>();
|
||||
public MergeStatus GetMergeStatus(string serialNumber)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _mergeStatuses.ContainsKey(serialNumber) ? _mergeStatuses[serialNumber] : null;
|
||||
}
|
||||
}
|
||||
public List<MergeStatus> GetMergeStatuses(List<string> serialNumbers)
|
||||
{
|
||||
var rv = new List<MergeStatus>();
|
||||
foreach (var sn in serialNumbers)
|
||||
{
|
||||
rv.Add(GetMergeStatus(sn));
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
public List<MergeStatus> GetAllMergeStatuses()
|
||||
{
|
||||
var rv = new List<MergeStatus>();
|
||||
lock (_lock)
|
||||
{
|
||||
rv.AddRange(_mergeStatuses.Values);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
public class MergeStatus
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the string for IsSensorInUse for the sensor
|
||||
/// </summary>
|
||||
public string BrokenDoNotUse { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the bool for a sensor with an EID that matches another sensor in the database
|
||||
/// </summary>
|
||||
public bool ConflictedEID { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the bool for a sensor with an EID that matches another sensor in the database
|
||||
/// </summary>
|
||||
public bool WarnConflictedEID { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the bool for a sensor that may match serial number and cal date but have different calibration information.
|
||||
/// </summary>
|
||||
public bool ConflictedSensor { get; set; }
|
||||
/// <summary>
|
||||
/// If true, the sensor did not get committed because of an error
|
||||
/// </summary>
|
||||
public bool Errored => ConflictedEID && ConflictedSensor && WarnConflictedEID || ErrorCommitingCal || MismatchedModelOrBridgeType;
|
||||
/// <summary>
|
||||
/// indicates that there was an error with the cal or the cal failed to be committed
|
||||
/// </summary>
|
||||
public bool ErrorCommitingCal { get; set; } = false;
|
||||
/// <summary>
|
||||
/// If true, the sensor did not get committed because there was newer/same information in the database.
|
||||
/// </summary>
|
||||
public bool Ignored { get; set; }
|
||||
/// <summary>
|
||||
/// If true, the sensor was committed or updated.
|
||||
/// </summary>
|
||||
public bool Committed { get; set; }
|
||||
/// <summary>
|
||||
/// If true, the input file had a mismatch in the Model or BridgeType column
|
||||
/// </summary>
|
||||
public bool MismatchedModelOrBridgeType { get; set; }
|
||||
}
|
||||
public SensorMerge(User currentUser)
|
||||
{
|
||||
_currentUser = currentUser;
|
||||
}
|
||||
public SensorMerge(User currentUser, List<SensorData> sensorDataToMerge, Dictionary<string, List<SensorCalibration>> sensorCalibrationsToMerge)
|
||||
{
|
||||
SensorDataMergeList = sensorDataToMerge;
|
||||
SensorCalibrationMergeList = sensorCalibrationsToMerge;
|
||||
_currentUser = currentUser;
|
||||
}
|
||||
public SensorMerge(User currentUser, List<SensorData> sensorDataToMerge, Dictionary<string, List<SensorCalibration>> sensorCalibrationsToMerge, Dictionary<int, int> oldSensorDatabaseIdToNew)
|
||||
{
|
||||
SensorDataMergeList = sensorDataToMerge;
|
||||
SensorCalibrationMergeList = sensorCalibrationsToMerge;
|
||||
OldSensorDatabaseIdToNew = oldSensorDatabaseIdToNew;
|
||||
_currentUser = currentUser;
|
||||
}
|
||||
|
||||
public void PerformWork()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
|
||||
_mergeStatuses = new Dictionary<string, MergeStatus>();
|
||||
|
||||
// Verify that SensorDataMergeList Contains the Calibration entries.
|
||||
// If it doesn't, add from the DB, if they exist there.
|
||||
foreach (var scList in SensorCalibrationMergeList)
|
||||
{
|
||||
var sn = scList.Value.FirstOrDefault()?.SerialNumber;
|
||||
if (string.IsNullOrEmpty(sn)) continue;
|
||||
if (SensorDataMergeList.Any(x => string.Equals(x.SerialNumber, sn))) continue;
|
||||
var existing = SensorsCollection.SensorsList.GetSensorBySerialNumber(sn);
|
||||
if (existing != null)
|
||||
{
|
||||
SensorDataMergeList.Add(existing);
|
||||
}
|
||||
}
|
||||
|
||||
//handle broken [true] before do not use
|
||||
//handle do not use [true] before regular.
|
||||
SensorDataMergeList.Sort((a, b) =>
|
||||
{
|
||||
if (a.Equals(b))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (a.Broken == b.Broken)
|
||||
{
|
||||
if (a.DoNotUse == b.DoNotUse)
|
||||
{
|
||||
return a.CompareTo(b);
|
||||
}
|
||||
return a.DoNotUse ? -1 : 1;
|
||||
}
|
||||
return a.Broken ? -1 : 1;
|
||||
});
|
||||
foreach (var sd in SensorDataMergeList)
|
||||
{
|
||||
try
|
||||
{
|
||||
_mergeStatuses[sd.SerialNumber] = new MergeStatus();
|
||||
var oldId = sd.DatabaseId;
|
||||
if (sd.Broken || sd.DoNotUse)
|
||||
{
|
||||
_mergeStatuses[sd.SerialNumber].BrokenDoNotUse = DTS.SensorDB.SensorsCollection.SensorsList.IsSensorInUse(sd);
|
||||
}
|
||||
if (sd.IsSquib() || sd.IsDigitalInput() || sd.IsDigitalOutput())
|
||||
{
|
||||
var existing =
|
||||
DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber(sd.SerialNumber);
|
||||
if (null == existing)
|
||||
{
|
||||
if (DTS.SensorDB.SensorsCollection.SensorsList.SensorIdExists(sd.EID))
|
||||
{
|
||||
//just fine, note it and don't commit it
|
||||
_mergeStatuses[sd.SerialNumber].WarnConflictedEID = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CommitToSensorList(sd, oldId);
|
||||
_mergeStatuses[sd.SerialNumber].Committed = true;
|
||||
}
|
||||
}
|
||||
else if (!existing.SimpleEquals(sd))
|
||||
{
|
||||
// Setting does not match. Update it.
|
||||
CommitToSensorList(sd, oldId);
|
||||
_mergeStatuses[sd.SerialNumber].Committed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mergeStatuses[sd.SerialNumber].Ignored = true;
|
||||
//just fine, note and move on (don't commit
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SensorCalibrationMergeList.ContainsKey(sd.UUID)) continue;
|
||||
var scNew = SensorCalibrationMergeList[sd.UUID].FirstOrDefault();
|
||||
var scOld = DTS.SensorDB.SensorCalibrationList.GetLatestCalibrationBySerialNumber(sd);
|
||||
var bCommit = false;
|
||||
if (null == scOld)
|
||||
{
|
||||
bCommit = true;
|
||||
if (DTS.SensorDB.SensorsCollection.SensorsList.SensorIdExists(sd.EID) &&
|
||||
(!sd.Broken || !sd.DoNotUse))
|
||||
{
|
||||
bCommit = false;
|
||||
_mergeStatuses[sd.SerialNumber].ConflictedEID = true;
|
||||
//ERROR
|
||||
}
|
||||
}
|
||||
else if (scOld.CalibrationDate.Date < scNew.CalibrationDate || sd.Broken || sd.DoNotUse)
|
||||
{
|
||||
bCommit = true;
|
||||
}
|
||||
else if (scOld.CalibrationDate == scNew.CalibrationDate)
|
||||
{
|
||||
bCommit = false;
|
||||
var sdOld = DTS.SensorDB.SensorsCollection.SensorsList.GetSensorBySerialNumber(sd.SerialNumber, false);
|
||||
if (null == sdOld || !sdOld.SimpleEquals(sd))
|
||||
{
|
||||
//if the cal dates are the same but the cal info is not, we've got an error
|
||||
//if the ids are the same, the cal dates are the same, and broken and do not use are all the same,
|
||||
//we've got nothing to update, so we've got an error
|
||||
//if broken/donotuse/id change do the update
|
||||
if (null != sdOld && (!scOld.SimpleEquals(scNew) ||
|
||||
sdOld.EID.Equals(sd.EID) && sdOld.Broken == sd.Broken && sd.DoNotUse == sdOld.DoNotUse))
|
||||
{
|
||||
_mergeStatuses[sd.SerialNumber].ConflictedSensor = true;
|
||||
//ERROR
|
||||
}
|
||||
else
|
||||
{
|
||||
//http://fogbugz/fogbugz/default.asp?10391
|
||||
//allow updating if the cal info is the same, and ids have changed
|
||||
//we might want to check that just the id changed ...
|
||||
bCommit = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//just fine, note it and don't commit it
|
||||
_mergeStatuses[sd.SerialNumber].Ignored = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bCommit) continue;
|
||||
try
|
||||
{
|
||||
CommitToSensorList(sd, oldId);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
//flag all 3 problems otherwise "Errored" isn't true with current rules
|
||||
_mergeStatuses[sd.SerialNumber].ConflictedEID = true;
|
||||
_mergeStatuses[sd.SerialNumber].ConflictedSensor = true;
|
||||
_mergeStatuses[sd.SerialNumber].WarnConflictedEID = true;
|
||||
APILogger.Log(ex);
|
||||
continue;
|
||||
}
|
||||
if (null != scNew && !scNew.SimpleEquals(scOld))
|
||||
{
|
||||
try
|
||||
{
|
||||
//avoid any dates which are invalid according to ms sql
|
||||
if (scNew.CalibrationDate.Year <= 1900)
|
||||
{
|
||||
_mergeStatuses[sd.SerialNumber].ErrorCommitingCal = true;
|
||||
APILogger.Log($"Invalid date: {scNew.CalibrationDate.ToShortDateString()} - {sd.SerialNumber}");
|
||||
continue;
|
||||
}
|
||||
SensorCalibrationList.Commit(scNew, true, sd);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
_mergeStatuses[sd.SerialNumber].ErrorCommitingCal = true;
|
||||
APILogger.Log(ex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
_mergeStatuses[sd.SerialNumber].Committed = true;
|
||||
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
if (ex.Message.Contains("can't change sensor to"))
|
||||
{
|
||||
_mergeStatuses[sd.SerialNumber].MismatchedModelOrBridgeType = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_mergeStatuses[sd.SerialNumber].ErrorCommitingCal = true;
|
||||
}
|
||||
APILogger.Log(ex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CommitToSensorList(SensorData sd, int oldId)
|
||||
{
|
||||
SensorsCollection.SensorsList.Commit(_currentUser.UserName, sd, false);
|
||||
if (sd.DatabaseId != oldId)
|
||||
{
|
||||
OldSensorDatabaseIdToNew[oldId] = sd.DatabaseId;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user