Files
DP44/Common/DTS.Common.DataModel/Classes/Arming/Arming.cs
2026-04-17 14:55:32 -04:00

606 lines
29 KiB
C#

using System;
using System.Collections.Generic;
using DTS.Common.Interface.DASFactory;
using DTS.Common.Utilities.Logging;
using DTS.DASLib.Service;
using System.Threading;
using System.Linq;
using DTS.Common.SharedResource.Strings;
using DTS.Common.DataModel.Common;
using DTS.Common.Enums.TSRAIRGo;
using DTS.Common.Constant.DASSpecific;
using DTS.Common.DataModel.Classes.TSRAIRGo;
namespace DataPROWin7.DataModel.Classes
{
public class Arming
{
readonly Configuration configuration = new Configuration();
public Arming()
{
}
public bool SetConfigAndFlashClear(DataModel.TestTemplate currentTest,
List<IDASCommunication> dasList,
Dictionary<string, int> dasSampleRateList,
double duration,
StatusHelpers.SetProgressValueDelegate setProgressFunction,
ServiceBase.ServiceCallbackErrorEventHandler onError)
{
return SetConfigAndStartFlashClear(currentTest, dasList, dasSampleRateList, duration, false, setProgressFunction, onError);
}
private bool SetConfigAndStartFlashClear(DataModel.TestTemplate currentTest,
List<IDASCommunication> dasList,
Dictionary<string, int> dasSampleRateList,
double duration,
bool diagnosticsVoltage,
StatusHelpers.SetProgressValueDelegate setProgressFunction,
ServiceBase.ServiceCallbackErrorEventHandler onError)
{
foreach (var das in dasList)
{
foreach (var mod in das.ConfigData.Modules)
{
mod.PostTriggerSeconds = duration;
mod.PreTriggerSeconds = (double)TSRAIR.TSRAIR_MAX_PRE_TRIGGER_SAMPLES / Convert.ToInt32(dasSampleRateList[das.SerialNumber]);
//FB 26980 mod.NumberOfEvents has already a correct value but override it to make sure the value is there
mod.NumberOfEvents = currentTest.NumberOfEvents;
mod.WakeUpMotionTimeout = currentTest.WakeUpMotionTimeout; //10?
}
}
try
{
foreach (var das in dasList)
{
setProgressFunction(das, 0D, TSRAIRGoStatus.StatusTypes.PREPARING_FOR_ARMING);
}
configuration.SetConfig(currentTest, dasList, diagnosticsVoltage, setProgressFunction);
foreach (var das in dasList)
{
setProgressFunction(das, 0D, TSRAIRGoStatus.StatusTypes.PREPARING_DATA_MEMORY);
}
return StartFlashClear(dasList, setProgressFunction, currentTest, onError);
}
catch (Exception ex)
{
onError?.Invoke(this, $"{StringResources.FailedToArm}: {ex.Message}", ex);
APILogger.Log(ex.Message);
return false;
}
}
protected bool StartFlashClear(List<IDASCommunication> dasList, StatusHelpers.SetProgressValueDelegate setProgressFunction,
DataModel.TestTemplate currentTest, ServiceBase.ServiceCallbackErrorEventHandler onError)
{
return FlashErase(dasList, setProgressFunction, currentTest, onError);
}
protected bool FlashErase(List<IDASCommunication> dasList, StatusHelpers.SetProgressValueDelegate setProgressFunction,
DataModel.TestTemplate currentTest, ServiceBase.ServiceCallbackErrorEventHandler onError)
{
var cancelEvent = new ManualResetEvent(false);
var resetEvent = new ManualResetEvent(false);
var bFailed = false;
var flashDevices = new List<IDASCommunication>(dasList);
var failureToClearFlashDevices = new List<IDASCommunication>();
lock (DASHardware.GetArmStatusLock)
{
if (flashDevices.Any())
{
using (var armingService = new ArmingService())
{
armingService.AggregateProgress = false;
var done = new ManualResetEvent(false);
var timeWaited = 0;
armingService.BeginFlashErase(flashDevices, delegate (ServiceBase.CallbackData cbd)
{
switch (cbd.Status)
{
case ServiceBase.CallbackData.CallbackStatus.Failure:
bFailed = true;
//39345 Don't hang if Flash Erase fails
cbd.Target.DASArmStatus.FaultMessage = StringResources.ArmSystem_FailedToClearFlash;
cbd.Target.SetDASArmStatus();
onError?.Invoke(this, string.Format(StringResources.ArmSystem_FailedToClearFlash, cbd.Target.SerialNumber), null);
failureToClearFlashDevices.Add(cbd.Target);
break;
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
done.Set();
break;
case ServiceBase.CallbackData.CallbackStatus.Success:
break;
}
}, flashDevices, false);
while (!cancelEvent.WaitOne(0, false) && !done.WaitOne(50, false))
{
timeWaited += 50;
}
}
}
//39345 Don't hang if Flash Erase fails
if (bFailed)
{
return false;
}
if (flashDevices.Any())
{
using (var armingService = new ArmingService())
{
armingService.AggregateProgress = false;
var bDone = false;
var flashStatus = new Dictionary<IDASCommunication, bool>();
foreach (var das in flashDevices)
{
flashStatus[das] = false;
}
while (!bDone)
{
var done = new ManualResetEvent(false);
var timeWaited = 0;
armingService.GetFlashEraseStatus(flashDevices, delegate (ServiceBase.CallbackData cbd)
{
switch (cbd.Status)
{
case ServiceBase.CallbackData.CallbackStatus.Failure:
bFailed = true;
flashStatus[cbd.Target] = true;
failureToClearFlashDevices.Add(cbd.Target);
onError?.Invoke(this, string.Format(StringResources.ArmSystem_FailedToClearFlash, cbd.Target.SerialNumber), cbd.ErrorException);
break;
case ServiceBase.CallbackData.CallbackStatus.Success:
flashStatus[cbd.Target] = true;
break;
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
{
using (var enumeratorFlashStatus = flashStatus.GetEnumerator())
{
var b = true;
while (enumeratorFlashStatus.MoveNext())
{
if (!enumeratorFlashStatus.Current.Value)
{
b = false;
}
}
bDone = b;
}
}
done.Set();
break;
case ServiceBase.CallbackData.CallbackStatus.Progress:
StatusHelpers.SetStatus2(cbd.Target, cbd.ProgressValue, TSRAIRGoStatus.StatusTypes.PREPARING_DATA_MEMORY, setProgressFunction);
if (100 <= cbd.ProgressValue)
{
flashStatus[cbd.Target] = true;
}
break;
}
}, flashDevices);
while (!cancelEvent.WaitOne(0, false) && !done.WaitOne(50, false))
{
timeWaited += 50;
}
if (cancelEvent.WaitOne(0, false))
{
bDone = true;
}
}
}
//39345 Don't hang if Flash Erase fails
if (bFailed)
{
return false;
}
}
}
if (!cancelEvent.WaitOne(0, false) && !bFailed)
{
return PrepareArmFunc(dasList, setProgressFunction, currentTest, onError);
}
else if (bFailed)
{
resetEvent.Set();
cancelEvent.Set();
return false;
}
return true;
}
protected bool PrepareArmFunc(List<IDASCommunication> dasList, StatusHelpers.SetProgressValueDelegate setProgressFunction, DataModel.TestTemplate currentTest,
ServiceBase.ServiceCallbackErrorEventHandler onError
)
{
const int ARM_NOW_TIMEOUT = 30000;
var cancelEvent = new ManualResetEvent(false);
var g = Guid.NewGuid();
var bFailedPrepareArm = false;
lock (DASHardware.GetArmStatusLock)
{
if (currentTest.LevelTriggerChannels.Count > 0)
{
using (var armService = new ArmingService())
{
var mre = new ManualResetEvent(false);
armService.CheckAlreadyLevelTriggered(dasList, delegate (ServiceBase.CallbackData cbd)
{
switch (cbd.Status)
{
case ServiceBase.CallbackData.CallbackStatus.Failure:
onError(this, $"{StringResources.ArmSystem_FailedArm} {cbd.ErrorMessage} - {cbd.Target.SerialNumber}", cbd.ErrorException);
bFailedPrepareArm = true;
break;
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
mre.Set();
break;
}
}, dasList);
mre.WaitOne();
var alreadyLevelTriggeredChannels = (from das in dasList where null != das.ConfigData from m in das.ConfigData.Modules from ch in m.Channels where ch is AnalogInputDASChannel let aCh = ch as AnalogInputDASChannel where aCh.AlreadyLevelTriggered select $"{das.SerialNumber} {1 + aCh.Number}").ToList();
if (alreadyLevelTriggeredChannels.Count > 0)
{
bFailedPrepareArm = true;
var errors = new List<string>();
errors.Add(StringResources.AlreadyLevelTriggeredChannels);
errors.AddRange(alreadyLevelTriggeredChannels.ToArray());
}
}
}
if (!bFailedPrepareArm)
{
using (var armService = new ArmingService())
{
var done = new ManualResetEvent(false);
var timeWaited = 0;
armService.ReadyForArm(dasList, delegate (ServiceBase.CallbackData cbd)
{
switch (cbd.Status)
{
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
done.Set();
break;
case ServiceBase.CallbackData.CallbackStatus.Progress:
StatusHelpers.SetStatus2(cbd.Target, cbd.ProgressValue, TSRAIRGoStatus.StatusTypes.PREPARING_FOR_ARMING, setProgressFunction);
break;
case ServiceBase.CallbackData.CallbackStatus.Success:
break;
case ServiceBase.CallbackData.CallbackStatus.Failure:
bFailedPrepareArm = true;
onError(this, $"{StringResources.ArmSystem_FailedArm} {cbd.ErrorMessage} - {cbd.Target.SerialNumber}", cbd.ErrorException);
break;
}
}, dasList, 600000, false, currentTest.NumberOfEvents, 0, g, false, dasList.Count > 1);
while (!cancelEvent.WaitOne(0, false) && !done.WaitOne(50, false))
{
timeWaited += 50;
}
}
}
if (!bFailedPrepareArm)
{
using (var armService = new ArmingService())
{
var done = new ManualResetEvent(false);
var timeWaited = 0;
armService.PrepareForArmNow(dasList, delegate (ServiceBase.CallbackData cbd)
{
switch (cbd.Status)
{
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
done.Set();
break;
case ServiceBase.CallbackData.CallbackStatus.Failure:
onError(this, $"{StringResources.ArmSystem_FailedArm} {cbd.ErrorMessage} - {cbd.Target.SerialNumber}", cbd.ErrorException);
bFailedPrepareArm = true;
break;
case ServiceBase.CallbackData.CallbackStatus.Success:
break;
case ServiceBase.CallbackData.CallbackStatus.Progress:
StatusHelpers.SetStatus2(cbd.Target, cbd.ProgressValue, TSRAIRGoStatus.StatusTypes.PREPARING_FOR_ARMING, setProgressFunction);
break;
}
}, dasList, ARM_NOW_TIMEOUT, false, currentTest.NumberOfEvents, g, dasList.Count > 1/* && CurrentTest.CommonLine*/);
while (!cancelEvent.WaitOne(0, false) && !done.WaitOne(50, false))
{
timeWaited += 50;
}
if (!cancelEvent.WaitOne(0, false))
{
done.Reset();
}
}
if (bFailedPrepareArm)
{
cancelEvent.Set();
return false;
}
}
else
{
cancelEvent.Set();
return false;
}
}
return ArmNowFunc(dasList, setProgressFunction, currentTest, onError);
}
protected bool ArmNowFunc(List<IDASCommunication> dasList, StatusHelpers.SetProgressValueDelegate setProgressFunction,
DataModel.TestTemplate currentTest, ServiceBase.ServiceCallbackErrorEventHandler onError)
{
var cancelEvent = new ManualResetEvent(false);
if (Common.SerializedSettings.StoreTestHistoryInDb)
{
//add code here?
}
var g = Guid.NewGuid();
var bFailedArm = false;
lock (DASHardware.GetArmStatusLock)
{
var bSomeoneArmed = false;
using (var armService = new ArmingService())
{
var done = new ManualResetEvent(false);
var timeWaited = 0;
done.Reset();
var disarmList = new List<IDASCommunication>();
PreparedArmNowFunc(dasList, g, ref bSomeoneArmed, ref bFailedArm, ref timeWaited, ref disarmList, setProgressFunction, currentTest,
onError);
//for safety reasons, make a disarm call to _everybody_ that "failed to arm", incase a module armed but the rack didn't
//http://fogbugz/fogbugz/default.asp?4527
if (done.WaitOne(0, false) && disarmList.Count > 0)
{
done.Reset();
bSomeoneArmed = false;
using (var aService = new ArmingService())
{
aService.Disarm(dasList, delegate (ServiceBase.CallbackData cbd)
{
switch (cbd.Status)
{
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
done.Set();
break;
}
}
, dasList);
}
while (!cancelEvent.WaitOne(0, false) && !done.WaitOne(50, false))
{ }
}
}
if (bSomeoneArmed)
{
if (!cancelEvent.WaitOne(0, false))
{
var das = new List<IDASCommunication>(dasList);
for (var i = das.Count - 1; i >= 0; i--)
{
if (null == das[i].DASArmStatus || das[i].DASArmStatus.IsArmed == false)
{
das.RemoveAt(i);
}
else
{
if (null != das[i].ConfigData && das[i].ConfigData.NumberOfConfiguredChannels() == 0 /*&& CareAboutNumberOfConfiguredChannels(das[i])*/)
{
das.RemoveAt(i);
}
}
}
var bFailedEnableFaultChecking = false;
var faultCheckingErrors = new List<string>();
//keeps track of whether we need to restore semaphores
//15630 limit EnableFaultChecking to single unit at a time for TDAS when there's a rack involved
if (das.Count > 1)
{
using (var armService = new ArmingService())
{
var done = new ManualResetEvent(false);
var timeWaited = 0;
armService.EnableFaultChecking(dasList, delegate (ServiceBase.CallbackData cbd)
{
switch (cbd.Status)
{
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
done.Set();
break;
case ServiceBase.CallbackData.CallbackStatus.Failure:
bFailedEnableFaultChecking = true;
faultCheckingErrors.Add($"{cbd.Target.SerialNumber} {StringResources.FailedEnableFaultChecking}");
onError(this, $"{StringResources.ArmSystem_FailedArm} {cbd.ErrorMessage} - {cbd.Target.SerialNumber}", cbd.ErrorException);
break;
}
}, das);
while (!cancelEvent.WaitOne(0, false) && !done.WaitOne(50, false))
{
timeWaited += 50;
}
}
}
//15267 Stop on ERR response from TDAS ARM RF
if (bFailedEnableFaultChecking)
{
DisarmAll(dasList);
cancelEvent.Set();
return false;
}
}
}
else if (bFailedArm)
{
cancelEvent.Set();
return false;
}
}
return true;
}
private void DisarmAll(List<IDASCommunication> das)
{
var mre = new ManualResetEvent(false);
using (var aService = new ArmingService())
{
aService.Disarm(das, delegate (ServiceBase.CallbackData cbd)
{
switch (cbd.Status)
{
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
mre.Set();
break;
}
}
, das);
}
mre.WaitOne();
}
private void PreparedArmNowFunc(List<IDASCommunication> dasList,
Guid g,
ref bool bSomeoneArmed,
ref bool bFailedArm,
ref int timeWaited,
ref List<IDASCommunication> lDisarmList,
StatusHelpers.SetProgressValueDelegate setProgressFunction,
DataModel.TestTemplate currentTest,
ServiceBase.ServiceCallbackErrorEventHandler onError)
{
var someoneArmed = false;
var failedArm = false;
var disarmList = new List<IDASCommunication>();
var doneEvent = new ManualResetEvent(false);
var cancelEvent = new ManualResetEvent(false);
var done = doneEvent;
using (var armService = new ArmingService())
{
armService.PreparedArmNow(dasList, delegate (ServiceBase.CallbackData cbd)
{
switch (cbd.Status)
{
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
done.Set();
break;
case ServiceBase.CallbackData.CallbackStatus.Failure:
onError(this, $"{StringResources.ArmSystem_FailedArm} {cbd.ErrorMessage} - {cbd.Target.SerialNumber}", cbd.ErrorException);
disarmList.Add(cbd.Target);
failedArm = true;
break;
case ServiceBase.CallbackData.CallbackStatus.Success:
if (!cbd.Target.IsEthernetDistributor())
{
someoneArmed = true;
try
{
if (null == cbd.Target.DASArmStatus) { cbd.Target.DASArmStatus = new ArmStatus(); }
cbd.Target.DASArmStatus.IsArmed = true;
cbd.Target.SetDASArmStatus();
}
catch (Exception ex)
{
APILogger.Log(ex.Message);
}
}
break;
case ServiceBase.CallbackData.CallbackStatus.Progress:
StatusHelpers.SetStatus2(cbd.Target, cbd.ProgressValue, TSRAIRGoStatus.StatusTypes.PREPARING_FOR_ARMING, setProgressFunction);
break;
}
}, dasList, 30000, false, currentTest.NumberOfEvents, g, dasList.Count > 1); ///////////fix the 30000 and 1 (at least)
}
while (!cancelEvent.WaitOne(0, false) && !done.WaitOne(50, false))
{
timeWaited += 50;
}
bSomeoneArmed = bSomeoneArmed || someoneArmed;
bFailedArm = bFailedArm || failedArm;
lDisarmList.AddRange(disarmList);
doneEvent = done;
}
public void SoftwareTrigger(List<IDASCommunication> dasList)
{
try
{
using (var armingService = new ArmingService())
{
lock (DASHardware.GetArmStatusLock)
{
var mre = new ManualResetEvent(false);
armingService.Trigger(dasList, delegate (ServiceBase.CallbackData data)
{
switch (data.Status)
{
case ServiceBase.CallbackData.CallbackStatus.AllFinished: mre.Set(); break;
case ServiceBase.CallbackData.CallbackStatus.Failure: APILogger.Log(data.ErrorMessage); break;
}
}, dasList);
while (!mre.WaitOne(10, false)) { }
}
}
}
catch (Exception ex)
{
APILogger.Log("Failure in Software Trigger");
APILogger.Log(ex);
}
}
public void DisarmAsync(List<IDASCommunication> dasList)
{
Disarm(dasList);
}
private void Disarm(List<IDASCommunication> dasList)
{
DisarmSync(dasList);
}
private void DisarmSync(List<IDASCommunication> dasList)
{
var mre = new ManualResetEvent(false);
using (var armingService = new ArmingService())
{
lock (DASHardware.GetArmStatusLock)
{
armingService.Disarm(
dasList,
delegate (ServiceBase.CallbackData data)
{
switch (data.Status)
{
case ServiceBase.CallbackData.CallbackStatus.AllFinished:
mre.Set();
break;
case ServiceBase.CallbackData.CallbackStatus.Canceled:
break;
case ServiceBase.CallbackData.CallbackStatus.Failure:
break;
case ServiceBase.CallbackData.CallbackStatus.Progress:
break;
case ServiceBase.CallbackData.CallbackStatus.Success:
break;
}
},
dasList);
while (!mre.WaitOne(10, false)) { }
}
}
}
}
}