using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using DTS.Common.DAS.Concepts; using System.Threading; using System.Windows.Forms; using DTS.Common.DASResource; using DTS.Common.Interface.DASFactory; using Arm = DTS.DASLib.Command.SLICE.Arm; using Disarm = DTS.DASLib.Command.SLICE.Disarm; using EnableFaultChecking = DTS.DASLib.Command.SLICE.EnableFaultChecking; using DTS.DASLib.Command.SLICE; using DTS.Common.Utilities.Logging; using System.Text; using DTS.DASLib.Service.Classes.SLICE; using System.Net.NetworkInformation; using DTS.Common.Enums; using DTS.Common.Enums.Sensors; using DTS.Common.Interface.Communication; using DTS.Common.Interface.Connection; using DTS.Common.Enums.DASFactory; using DTS.Common.ICommunication; using DTS.Common.Interface.StatusAndProgressBar; using DTS.Common.Utilities; using DTS.DASLib.Command.SLICE.DownloadCommands; using DTS.DASLib.Command.SLICEDB; using DTS.Common.Constant.DASSpecific; using DTS.Common.Enums.Hardware; using DisableFaultChecking = DTS.DASLib.Command.SLICE.DisableFaultChecking; using DTS.Common; namespace DTS.DASLib.Service { public class PowerPro : PowerPro_Base, //IDASReconfigure, IDASCommunication, IConfigurationActions, IDiagnosticsActions, ITriggerCheckActions, IRealTimeActions, IArmActions, IDownloadActions where T : IConnection, new() { protected override void AsyncConfigure(object configAsyncInfo) { var info = (SliceConfigServiceAsyncInfo)configAsyncInfo; if (ConfigData != null && ConfigData.Modules.Any()) { try { var saa = new SetArmAttribute(this); saa.SetValue(AttributeTypes.ArmAndEventAttributes.SampleRate, ConfigData.Modules[0].SampleRateHz, true); saa.SyncExecute(); } catch (Exception ex) { APILogger.Log("failed to configure", SerialNumber, ex); info.Error(ex.Message); return; } } base.AsyncConfigure(configAsyncInfo); } public override string ConvertInputVoltage2BatteryCharging(double inputVoltage) { bool isCharging; var SwitchQuery = new QuerySwitchImmediate(this) { DeviceID = 0, Switch = (byte)Switches.PowerProSwitches.ChargePower }; try { SwitchQuery.SyncExecute(); if (1 == SwitchQuery.Setting) { isCharging = true; } else { isCharging = false; } } catch (Exception) { isCharging = false; } // If we are charging if (isCharging) { return Resources.Charging; } // If we aren't charging and input is valid else if (inputVoltage > MinimumValidInputVoltage && inputVoltage < MaximumValidInputVoltage) { return Resources.NotCharging; } // If we're off input voltage and not charging else { return Resources.Discharging; } } public override bool? ChargingEnabled { get { return true; } } void IDASCommunication.SetIsStreamingSupported(bool supported) { IsStreamingSupported = false; } void IDASCommunication.ReadFirstUseDate() { IsFirstUseDateSupported = false; FirstUseDate = null; } /// /// indicates date of first use /// null indicates the hardware has not been used since calibration /// only valid when IsFirstUseDateSupported is true /// 15524 DAS "First Use Date" /// public DateTime? FirstUseDate { get; set; } = null; /// /// returns whether the hardware supports first use or not /// for hardware to support first use the hardware must support /// storage for user attributes in firmware and also have been /// calibrated by software support hardware first use /// 15524 DAS "First Use Date" /// public bool IsFirstUseDateSupported { get; set; } = false; /// /// returns true if the devices is an ethernet distributor /// for now that is SLICEDb, SLICE ECM, SLICE6DB /// these are devices that we talk through, but not to for device communication /// a rack we communicate with the modules by talking to the rack, so it's not a distributor /// /// returns true if the devices is an ethernet distributor public override bool IsEthernetDistributor() { return true; } public override bool IsSlice6Distributor() { return false; } public override bool IsBattery() { return true; } public override bool IsTSRAIR() { return false; } public bool IsSlice6Air() { return false; } public override bool IsScheduleEventCountSupported() { return false; } void IConfigurationActions.SetFirstUseDate(DateTime firstUseDate, ServiceCallback callback, object userData) { var info = new PowerProAsyncInfo(callback, userData); info.Error("Not supported"); } /// /// Figure out if events have been downloaded /// /// The function to call with information /// Whatever you want to pass along public void QueryDownloadedStatus(ServiceCallback callback, object userData) { var info = new PowerProAsyncInfo(callback, userData); info.Success(); } /// /// Verify that the ConfigData property is correctly constructed /// /// Set to true if your're arming public void VerifyConfig(bool DoStrictCheck) { VerifyConfig(DoStrictCheck, null); } public void VerifyConfig(bool DoStrictCheck, ErrorCallback failedChallengeFunc) { if (!DoStrictCheck) return; if (!IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines)) return; var query = new InitializeHardwareLines(this) { CheckStartForShort = true, CheckTriggerForShort = true }; try { query.SyncExecute(); if (query.StartRecordShorted && !IgnoreShortedStart) { //Start Shorted throw new StartShortedException(string.Format(Strings.StartRecordShorted, SerialNumber)); } if (query.TriggerInputShorted && !IgnoreShortedTrigger) { //Trigger Shorted throw new TriggerShortedException(string.Format(Strings.TriggerShorted, SerialNumber)); } } catch (Exception ex) { InitializeHardwareLines.Log(ex, query); } } void IArmActions.ReArm(ServiceCallback callback, object userData, bool autoArm, bool arm, bool repeatEnable) { var info = new PowerProAsyncInfo(callback, userData); info.Error("NotSupported"); } public void PreparedArmNow(ServiceCallback callback, object userData, Guid eventGuid, int armNowTimeout, bool testingMode, int maxNumberEvents, bool SysMode) { var info = new PowerProAsyncInfo(callback, userData); try { if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel)) { var mppadc = new MeasurePowerProAllDiagnosticChannel(this); mppadc.SyncExecute(); // Just Log it for now } } catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); } var saa = new SetArmAttribute(this); var postTriggerSamples = Convert.ToUInt64(ConfigData.Modules[0].PostTriggerSeconds * ConfigData.Modules[0].SampleRateHz); saa.SetValue(AttributeTypes.ArmAndEventAttributes.PostTriggerSamplesRequested, postTriggerSamples, true); saa.SyncExecute(); saa = new SetArmAttribute(this); var preTriggerSamples = 0UL; if (ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.CircularBuffer || ConfigData.Modules[0].RecordingMode == DFConstantsAndEnums.RecordingMode.CircularBufferPlusUART) { preTriggerSamples = Convert.ToUInt64(Math.Abs(ConfigData.Modules[0].PreTriggerSeconds * ConfigData.Modules[0].SampleRateHz)); } saa.SetValue(AttributeTypes.ArmAndEventAttributes.PreTriggerSamplesRequested, preTriggerSamples, true); saa.SyncExecute(); SetArmMode(ConfigData.Modules[0].RecordingMode); try { var arm = new Arm(this); arm.SyncExecute(); //17812 DataPRO does not issue EnableFaultChecking when running with POWER PRO and a single DAS //UI code was setting this for non ethernet distributors DASArmStatus.IsArmed = true; SetDASArmStatus(); } catch (Exception) { info.Success(); //TEMP until PowerPro Event line is not shorted return; } info.Success(); } /// /// Perform diagnostics based on the property ChannelDiagnostics and stuff the /// result in ChannelDiagnosticsResults /// /// sample rate /// AA Filter rate /// /// The function to call with information /// Whatever you want to pass along void IDiagnosticsActions.PrepareForDiagnostics(uint diagnosticsSampleRateHz, float diagnosticsAAFilterFrequencyHz, PrePostResults whichResult, ServiceCallback callback, object userData) { var info = new PowerProAsyncInfo(callback, userData); info.Success(); } /// /// Perform diagnostics based on the property ChannelDiagnostics and stuff the /// result in ChannelDiagnosticsResults /// /// The function to call with information /// Whatever you want to pass along public void DiagnosAndGetResults(int EventNumber, PrePostResults WhichResult, ServiceCallback callback, object userData) { var info = new PowerProAsyncInfo(callback, userData); DiagnosticsHasBeenRun = true; BaseInput = new BaseInputValues(); GetBaseInputs(true); ClearChannelDiagnosticsResults(false); info.Success(); } public override double MaximumValidInputVoltage { get; set; } = 26D; public void PerformArmChecks(ServiceCallback callback, object userData) { var info = new PowerProAsyncInfo(callback, userData); LaunchAsyncWorker("PowerPro.PerformArmChecks", new WaitCallback(AsyncPerformArmChecks), info); } private void AsyncPerformArmChecks(object o) { var info = o as PowerProAsyncInfo; var dasResults = new ArmCheckResults(); info.Progress(25); if (null != ArmCheckActions) { GetBaseInputs(true); if (ArmCheckActions.PerformInputVoltageCheck || ArmCheckActions.PerformBatteryVoltageCheck) { try { if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel)) { var mppadc = new MeasurePowerProAllDiagnosticChannel(this); mppadc.SyncExecute(); // Just Log it for now } } catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); } } if (ArmCheckActions.PerformBatteryVoltageCheck) { //if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics)) //{ try { dasResults.BatteryVoltage = new double?[1]; dasResults.BatteryVoltage[0] = BaseInput.BatteryMilliVolts / 1000D; } catch (Exception ex) { APILogger.Log("Failed to get Battery voltage", ex); } //} } info.Progress(33); if (ArmCheckActions.PerformInputVoltageCheck) { //if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics)) //{ try { dasResults.InputVoltage = BaseInput.InputMilliVolts / 1000D; } catch (Exception ex) { APILogger.Log("Failed to get Input voltage", ex); } //} } info.Progress(66); if (ArmCheckActions.PerformSquibResistanceCheck) { // No Squibs in PowerPro } if (ArmCheckActions.PerformEventLineCheck) { ((ITriggerCheckActions)this).DoTriggerCheckSync(); } if (ArmCheckActions.PerformSensorIdCheck) { //not needed } if (ArmCheckActions.PerformTemperatureCheck) { //// Temperature //dasResults.TemperaturesPre = new float[] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN }; //var measure = new MeasureS6DBDiagnosticChannel(this); ////External sensor 1 //measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_2_Temperature; //measure.SyncExecute(); //dasResults.TemperaturesPre[0] = measure.Measurement; ////External sensor 2 //measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_3_Temperature; //measure.SyncExecute(); //dasResults.TemperaturesPre[1] = measure.Measurement; ////External sensor 3 //measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_4_Temperature; //measure.SyncExecute(); //dasResults.TemperaturesPre[2] = measure.Measurement; ////External sensor 4 //measure.Channel = MeasureS6DBDiagnosticChannel.S6DBDiagnosticChannelList.DiagEnv_5_Temperature; //measure.SyncExecute(); //dasResults.TemperaturesPre[3] = measure.Measurement; } } info.Progress(100); dasResults.SensorIds = null; dasResults.TiltSensorDataPre = null; dasResults.SquibResistances = null; ArmCheckResults = dasResults; info.Success(); } public void CheckAlreadyLevelTriggered(ServiceCallback callback, object userData) { var info = new PowerProAsyncInfo(callback, userData); LaunchAsyncWorker("PowerPro.CheckAlreadyLevelTriggered", AsyncCheckAlreadyLevelTriggered, info); } private void AsyncCheckAlreadyLevelTriggered(object asyncInfo) { var info = asyncInfo as PowerProAsyncInfo; Debug.Assert(info != null, "info != null"); try { foreach (var m in ConfigData.Modules) { foreach (var ch in m.Channels) { if (!(ch is AnalogInputDASChannel analog)) continue; analog.AlreadyLevelTriggered = false; analog.MeasuredEULevelTriggerCheck = double.NaN; } } info.Success(); } catch (Exception ex) { info.Error(ex.Message, ex); } } public void DoTriggerCheck(ServiceCallback callback, object userData) { //this was supposed to be async, why is it executing synchronously? I dont' know //but I'm preserving it as is [dtm] 2019-05-23 PowerProAsyncInfo info = null; if (null != callback) { info = new PowerProAsyncInfo(callback, userData); } DoTriggerCheckSync(); info?.Success(); } /// /// do the synchronous version of trigger check /// public void DoTriggerCheckSync() { if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines)) { var query = new InitializeHardwareLines(this) { LogCommands = true, CheckStartForShort = true, CheckTriggerForShort = true }; try { try { query.SyncExecute(); } catch (Exception ex) { //IHL can throw an exception if the trigger is shorted, we don't want this //but if it's anything else go and rethrow the exception if (!ex.Message.ToLower().Contains("shorted")) { throw; } } //var oldStatus = DASArmStatus; var status = new ArmStatus { IsTriggered = query.TriggerInputShorted, //IsArmed = query.TriggerInputShorted || query.StartRecordShorted IsStartShorted = query.StartRecordShorted }; //10601 Trigger Check can miss the pulse generated by HW //we have to latch the trigger status for the S6DB ... since it does one shot pulse //if (null != oldStatus) //{ // status.IsArmed = status.IsArmed || oldStatus.IsArmed; // status.IsTriggered = status.IsTriggered || oldStatus.IsTriggered; // status.IsStartShorted = status.IsStartShorted || oldStatus.IsStartShorted; //} status.IsTriggerShorted = status.IsTriggered; //status.IsStartShorted = status.IsArmed; status.IsStartShorted = status.IsStartShorted; SetDASArmStatus(status, true); } catch (Exception ex) { InitializeHardwareLines.Log(ex, query); } } } void ITriggerCheckActions.PostStartTriggerCheck(ServiceCallback callback, object userData) { var info = new PowerProAsyncInfo(callback, userData); info.Success(); } private class EventDiagnosticsAsyncPacket { public PowerProAsyncInfo Info { get; set; } public int EventNumber { get; set; } public PrePostResults WhichResult { get; set; } } /// /// Retrieve the results from the implicit pre and post event diagnostics /// /// Which event number to Retrieve from /// The pre or post test results? /// The function to call with information /// Whatever you want to pass along public void GetEventDiagnosticsResults(int EventNumber, PrePostResults WhichResult, ServiceCallback callback, object userData) { var packet = new EventDiagnosticsAsyncPacket(); packet.Info = new PowerProAsyncInfo(callback, userData); packet.EventNumber = EventNumber; packet.WhichResult = WhichResult; packet.Info.Success(); } public void PerformVoltageCheckTAOnly(ServiceCallback callback, object userData) { var info = new PowerProAsyncInfo(callback, userData); LaunchAsyncWorker("PowerPro.PerformVoltageCheckTAOnly", AsyncPerformVoltageCheckTAOnly, info); } private void AsyncPerformVoltageCheckTAOnly(object o) { var info = o as PowerProAsyncInfo; info?.Success(); } private const double SDB_ERR_VOLTAGE_REPORTING = 100000.0D; /// /// Retrieve the current arm status from the DAS /// /// The function to call with information /// Whatever you want to pass along //void IArmActions.GetArmStatus(ServiceCallback callback, object userData, uint inputVoltageCutoff) //{ // var info = new PowerProAsyncInfo(callback, userData); // var status = new ArmStatus { IsArmed = false }; // try // { // try // { // if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel)) // { // var mppadc = new MeasurePowerProAllDiagnosticChannel(this); // mppadc.SyncExecute(); // Just Log it for now // } // } // catch (Exception ex) { APILogger.Log("Failed to Measure All Diagnostic Channel", ex); } // if (IsCommandSupported(DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics)) // { // var batteryVoltage = 0.0; // try // { // var query = new QueryBatteryVoltageMV(this, 3000); // query.SyncExecute(); // var d = (double)query.BatteryVoltageMV; // if (d > SDB_ERR_VOLTAGE_REPORTING) // { // d /= 1000.0D; // } // status.BatteryMilliVolts = d; // batteryVoltage = Math.Round(d / 1000, 1); // } // catch (Exception ex) // { // APILogger.Log("Failed to get battery mv", ex); // } // try // { // var query = new QueryV1VoltageMV(this, 3000); // query.SyncExecute(); // var d = (double)query.V1VoltageMV; // if (d > SDB_ERR_VOLTAGE_REPORTING) // { // d /= 1000.0D; // } // status.InputMilliVolts = d; // var inputVoltage = Math.Round(d / 1000, 1); // if (batteryVoltage < MinimumValidBatteryVoltage || batteryVoltage > MaximumValidBatteryVoltage) // { // batteryVoltage = 0.0; // } // BaseInput = new BaseInputValues(); // var batteryVoltageStatusColor = DFConstantsAndEnums.VoltageStatusColor.Off; // batteryVoltageStatusColor = BaseInput.ChargeCapacityValid // ? ConvertBatteryCapacity2Color(batteryVoltage, BaseInput.ChargeCapacity) // : ConvertBatteryVoltage2Color(batteryVoltage); // var batteryChargingStatus = string.Empty; // if (batteryVoltage >= MinimumValidBatteryVoltage) // { // batteryChargingStatus = ConvertInputVoltage2BatteryCharging(inputVoltage); // } // var statusDisplayBattery = // batteryVoltage < MinimumValidBatteryVoltage || batteryVoltage > MaximumValidBatteryVoltage // ? "---" // : batteryVoltage.ToString(System.Globalization.CultureInfo.InvariantCulture) + " V " + // batteryChargingStatus; // var inputVoltageStatusColor = ConvertInputVoltage2Color(inputVoltage); // BaseInput.InputVoltageStatusColor = inputVoltageStatusColor; // BaseInput.StatusDisplayInput = // inputVoltage < MinimumValidInputVoltage || inputVoltage > MaximumValidInputVoltage // ? "---" // : inputVoltage.ToString(System.Globalization.CultureInfo.InvariantCulture) + " V"; // BaseInput.BatteryVoltageStatusColor = batteryVoltageStatusColor; // BaseInput.StatusDisplayBattery = statusDisplayBattery; // } // catch (Exception ex) // { // APILogger.Log("Failed to get input mv", ex); // } // } // } // finally // { // SetDASArmStatus(status, true); // } // info.Success(); //} void IConfigurationActions.CheckSafetyState(bool bArmed, ServiceCallback callback, object userData) { var info = new PowerProAsyncInfo(callback, userData); info.Success(); } //} /// /// this is a duplicate class of SLICEDb.SDBAsyncInfo, we might want to just use that one, but it is marked private there /// private class PowerProAsyncInfo { public ServiceCallback Callback { get; set; } public object UserData { get; set; } public object FunctionData { get; set; } public PowerProAsyncInfo(ServiceCallback callback, object userData) { Callback = callback; UserData = userData; } public void Error(string msg, Exception ex) { try { var cbData = new ServiceCallbackData(); cbData.Status = ServiceCallbackData.CallbackStatus.Failure; cbData.ErrorMessage = msg; cbData.ErrorException = ex; cbData.UserData = UserData; Callback(cbData); } catch (Exception eex) { APILogger.Log("MessageBox", "PowerPRO ERROR", eex); } } public void Error(string msg) { Error(msg, null); } public void Progress(int value) { try { var progressData = new ServiceCallbackData(); progressData.Status = ServiceCallbackData.CallbackStatus.ProgressReport; progressData.ProgressValue = value; progressData.UserData = UserData; Callback(progressData); } catch (Exception ex) { APILogger.Log("MessageBox", "PowerPRO ERROR", ex); } } public void Success() { try { var success = new ServiceCallbackData(); success.Status = ServiceCallbackData.CallbackStatus.Success; success.UserData = UserData; Callback(success); } catch (Exception ex) { APILogger.Log("MessageBox", "PowerPRO ERROR", ex); } } public void Cancel() { try { var cancelReport = new ServiceCallbackData(); cancelReport.Status = ServiceCallbackData.CallbackStatus.Canceled; cancelReport.ProgressValue = 0; cancelReport.UserData = UserData; Callback(cancelReport); } catch (Exception ex) { APILogger.Log("MessageBox", "PowerPRO ERROR", ex); } } } } public class PowerPro_Base : SLICE2_Base where T : IConnection, new() { protected override bool AdjustInputRange(AnalogInputDASChannel analog) { return false; } /// /// returns true if device supports trigger inversion, false otherwise /// /// /// true if device supports trigger inversion, false otherwise public override bool SupportsTriggerInversion() => HardwareConstants.SupportsTriggerInversion(GetHardwareType(), ProtocolVersion); /// /// returns true if device supports start inversion, false otherwise /// /// /// true if device supports start inversion, false otherwise public override bool SupportsStartInversion() => HardwareConstants.SupportsStartInversion(GetHardwareType(), ProtocolVersion); public override bool CheckAAF(float rate) { return true; } public override bool SupportsTimeSynchronization { get { return true; } } public override double[] GetNominalRanges(SensorConstants.BridgeType bridgeType) { switch (bridgeType) { case SensorConstants.BridgeType.IEPE: return WinUSBSlice.StaticDASIEPEInfo.NominalRanges; default: return WinUSBSlice.StaticDASBridgeInfo.NominalRanges; } } private readonly Dictionary PowerPro_MinimumProtocols = new Dictionary(); public override void InitMinProto() { // SLICE 6.0 DB Protocol Limitations PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryMSP430Firmware] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleAndHybridEvents] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleEvents] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArm] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetDefaultMIF] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.FileData] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackSensors] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseSystemTime] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.TestCommunication] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackLowPowerMode] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SetRealtimeSampleRate] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.SLICE2_OneWireID] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareRevision] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.HardwareConfiguration] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventFaultFlags] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.EventArmAttempts] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryActualSampleRateImmediate] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.InitHardwareInputLines] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageSysAttributes] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.LevelTrigger] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AttributeStoreBlocks] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryArmAndTriggerStatus_VoltageReadings] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MaxEvents] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.AutoArmDiagnosticDelay] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.StackChannelAutoArmDiagLevel] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MultipleSamplesRealtime] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.BaseCalibrationDate] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.IgnoreShortedStartEvent] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.ResetAttributeStore] = PowerPRO.MIN_PROTOCOL_VER; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.DiangosShuntDAC] = PowerPRO.DIAGNOS_SHUNT_DAC; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.VoltageInsertion] = PowerPRO.DIAGNOS_SHUNT_DAC; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.QueryEthernetMacTable] = PowerPRO.MIN_PROTOCOL_QUERYMACTABLE; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.MeasurePowerProAllDiagnosticChannel] = PowerPRO.MIN_PROTOCOL_MEASUREPOWERPROALLDIAGNOSTICCHANNEL; PowerPro_MinimumProtocols[DFConstantsAndEnums.ProtocolLimitedCommands.Diagnostics] = PowerPRO.MIN_PROTOCOL_VER; MinimumProtocols = PowerPro_MinimumProtocols; } protected override Slice.ConfigAttributes GetConfigAttributes(ICommunication com) { return new SLICE6ConfigAttributes(com); } /// /// SLICE6 config attributes, mostly inherits from SLICE.ConfigAttributes with some functionality removed /// protected class SLICE6ConfigAttributes : Slice.ConfigAttributes { public SLICE6ConfigAttributes(ICommunication _com) : base(_com) { } } /// /// QueryEventData also is customized for SLICE6, it needs to perform SLICE6 specific data marshalling /// /// protected override QueryEventDataBase GetQueryEventData() { return new QueryEventData_SLICE6(this, QueryEventData_SLICE6.Default_IO_Timeout); } /// /// we can probably simplify and take common items (slice6+slice1) out of this function, but for now /// it's mostly a copy of SLICE1.AsyncConfigure /// /// protected override void AsyncConfigure(object configAsyncInfo) { var info = (SliceConfigServiceAsyncInfo)configAsyncInfo; ConfigureHasBeenRun = true; if (info.DiscardDiagnostics) { DiagnosticsHasBeenRun = false; } info.Progress(100); info.Success(); } #region Voltage Check public void PerformVoltageCheck(ServiceCallback callback, object userData) { var info = new SliceServiceAsyncInfo(callback, userData); LaunchAsyncWorker("PowerPro.PerformVoltageCheck", AsyncPerformVoltageCheck, info); } private void AsyncPerformVoltageCheck(object o) { var info = o as SliceServiceAsyncInfo; try { GetBaseInputs(true); info?.Success(); } catch (Exception ex) { APILogger.Log(ex); info?.Error(ex.Message); } } #endregion /// /// hardcoded constants right now ... maybe these belong in attributes in the firmware! /// protected override uint MaxAAFilterRateHz { get { return PowerPRO.MaxAAFilterRateHz; } } protected override uint MaxSampleRateHz { get { return 400000; } } } }