Hello,
I am using a DataMiner automation to make multiple QAction calls in a custom CAP-1010 Driver, however I am getting inconsistent results with having either some or all of the QActions successfully firing off.
the QAction fires when there is a parameter change in one of the cells in my table.
are there any changes i can make/ tools i can utilize to make my automations more reliable?
cheers,
attached is the UI of the table in DM and my Automation code.
the following is my QAction code:
using System;
using System.Text;
using Skyline.DataMiner.Scripting;/// <summary>
/// DataMiner QAction Class.
/// </summary>
public static class QAction
{
/// <summary>
/// The QAction entry point.
/// </summary>
/// <param name="protocol">Link with SLProtocol process.</param>
public static void Run(SLProtocol protocol)
{
try
{
CreateGroomMPEGStop(protocol);
}
catch (Exception ex)
{
protocol.Log($"QA{protocol.QActionID}|{protocol.GetTriggerParameter()}|Run|Exception thrown:{Environment.NewLine}{ex}", LogType.Error, LogLevel.NoLogging);
}
}public static void CreateGroomMPEGStop(SLProtocol protocol)
{
// protocol.Log("creating splice...");
var outputID = protocol.RowIndex();DeviceData deviceData = new DeviceData
{
Manager = protocol.GetParameter(Parameter.devicename),
Farmer = protocol.GetParameter(Parameter.farmerid),
SID = protocol.GetParameter(Parameter.sid),
DeviceVersion = protocol.GetParameter(Parameter.deviceversionapi),
};// get output data
object[] outputRowData = (object[])protocol.GetRow(Parameter.Spliceoutputprograms.tablePid, outputID);
OutputProgramData outputSpliceData = new OutputProgramData
{
Name = Convert.ToString(outputRowData[Parameter.Spliceoutputprograms.Idx.spliceoutputprogramsname]),
Line = Convert.ToString(outputRowData[Parameter.Spliceoutputprograms.Idx.spliceoutputprogramsline]),
ID = Convert.ToString(outputRowData[Parameter.Spliceoutputprograms.Idx.spliceoutputprogramsid]),
ProgramNumber = Convert.ToString(outputRowData[Parameter.Spliceoutputprograms.Idx.spliceoutputprogramsdestinationnumber]),
};// protocol.Log($"output {outputSpliceData.Name}, line {outputSpliceData.Line}, id {outputSpliceData.ID}, program {outputSpliceData.ProgramNumber}");
// get input data
string inputID = Convert.ToString(outputRowData[Parameter.Spliceoutputprograms.Idx.spliceoutputprogramsinputid]);
if (inputID.Length != 4)
{
protocol.SetParameter(Parameter.splicestatus, 2);
return;
}object[] inputRowData = (object[])protocol.GetRow(Parameter.Spliceinputprograms.tablePid, "i" + inputID);
if (inputRowData == null)
{
protocol.SetParameter(Parameter.splicestatus, 3);
return;
}InputProgramData inputSpliceData = new InputProgramData
{
Name = Convert.ToString(inputRowData[Parameter.Spliceinputprograms.Idx.spliceinputprogramsname]),
Line_Pr = Convert.ToString(inputRowData[Parameter.Spliceinputprograms.Idx.spliceinputprogramslineprimary]),
ID_Pr = Convert.ToString(inputRowData[Parameter.Spliceinputprograms.Idx.spliceinputprogramsidprimary]),
ProgramNumber_Pr = Convert.ToString(inputRowData[Parameter.Spliceinputprograms.Idx.spliceinputprogramsnumberprimary]),
Line_Bkp = Convert.ToString(inputRowData[Parameter.Spliceinputprograms.Idx.spliceinputprogramslinebackup]),
ID_Bkp = Convert.ToString(inputRowData[Parameter.Spliceinputprograms.Idx.spliceinputprogramsidbackup]),
ProgramNumber_Bkp = Convert.ToString(inputRowData[Parameter.Spliceinputprograms.Idx.spliceinputprogramsnumberbackup]),
};// protocol.Log($"input {inputSpliceData.Name}, line {inputSpliceData.Line_Pr}, linebk {inputSpliceData.Line_Bkp}, id {inputSpliceData.ID_Pr}, idbk {inputSpliceData.ID_Bkp}, program {inputSpliceData.ProgramNumber_Pr}, programbk {inputSpliceData.ProgramNumber_Bkp}");
// get max rate
object[] outputMuxRowData = (object[])protocol.GetRow(Parameter.Outputmuxes.tablePid, $"{outputSpliceData.Line}:{outputSpliceData.ID}");
string maxBitRate = Convert.ToString(outputMuxRowData[Parameter.Outputmuxes.Idx.outputmuxestotalrate]);try
{
string time = DateTime.Now.ToString("ddd MMM d HH:mm: ss zzz yyyy");
string groomDescription = $"{outputSpliceData.Name}-{inputSpliceData.Name}";StringBuilder createGroomRequest = new StringBuilder();
createGroomRequest.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
createGroomRequest.AppendLine($"<request id=\"dataminer_controller\" origin=\"cap1010_programGroom_QA_{protocol.ElementName}\" destination=\"device\" command=\"add\" category=\"groom\" time=\"{time}\" protocol-version=\"{deviceData.DeviceVersion}\" platform-name=\"CAP-1000\" sid=\"{deviceData.SID}\" >");
createGroomRequest.AppendLine("<path>");
createGroomRequest.AppendLine($"<manager id=\"{deviceData.Manager}\" />");
createGroomRequest.AppendLine($"<farmer id=\"{deviceData.Farmer}\" />");
createGroomRequest.AppendLine($"<gige-output-line id=\"{outputSpliceData.Line}\" />");
createGroomRequest.AppendLine($"<gige-output-mux id=\"{outputSpliceData.ID}\" />");
createGroomRequest.AppendLine($"<output-program id=\"{outputSpliceData.ProgramNumber}\" />");
createGroomRequest.AppendLine("</path>");
createGroomRequest.AppendLine("<action-defs force-disable-mred=\"false\" >");
createGroomRequest.AppendLine($"<prog-groom description=\"{groomDescription}\" encrypt-by-default=\"false\" cue-insertion-enabled=\"false\" cue-insertion-dpi-disabled=\"false\" pass-streams=\"false\" pass-descriptor=\"auto-pass-exclude-ca\" cue-conversion-enabled=\"false\" priority=\"5\" min-video-bit-rate=\"0\" max-video-bit-rate=\"{maxBitRate}\" >");
createGroomRequest.AppendLine("<primary stop-mpeg-enabled=\"true\" stop-mpeg-error-period-secs=\"5\" stop-mpeg-non-underflow-error-secs=\"-1\" stop-mpeg-trigger-streams=\"all-video-audio\" stop-mpeg-auto-resume=\"true\" stop-mpeg-error-free-period-secs=\"12\"> ");
createGroomRequest.AppendLine("<input>");
createGroomRequest.AppendLine("<path>");
createGroomRequest.AppendLine($"<manager id=\"{deviceData.Manager}\" />");
createGroomRequest.AppendLine($"<farmer id=\"{deviceData.Farmer}\" />");
createGroomRequest.AppendLine($"<gige-input-line id=\"{inputSpliceData.Line_Pr}\" />");
createGroomRequest.AppendLine($"<gige-input-mux id=\"{inputSpliceData.ID_Pr}\" />");
createGroomRequest.AppendLine($"<input-program id=\"{inputSpliceData.ProgramNumber_Pr}\" />");
createGroomRequest.AppendLine("</path>");
createGroomRequest.AppendLine("<map in-pid=\"-1\" type=\"-1\" />");
createGroomRequest.AppendLine("</input>");
createGroomRequest.AppendLine("</primary>");
createGroomRequest.AppendLine("<redundancy type=\"program\" switch-immediate=\"true\" back-to-primary=\"true\" underflow-alarm-switch=\"all-video-audio\" underflow-interval=\"2\" no-alarm-period=\"12\" >");
createGroomRequest.AppendLine("<input>");
createGroomRequest.AppendLine("<path>");
createGroomRequest.AppendLine($"<manager id=\"{deviceData.Manager}\" />");
createGroomRequest.AppendLine($"<farmer id=\"{deviceData.Farmer}\" />");
createGroomRequest.AppendLine($"<gige-input-line id=\"{inputSpliceData.Line_Bkp}\" />");
createGroomRequest.AppendLine($"<gige-input-mux id=\"{inputSpliceData.ID_Bkp}\" />");
createGroomRequest.AppendLine($"<input-program id=\"{inputSpliceData.ProgramNumber_Bkp}\" />");
createGroomRequest.AppendLine("</path>");
createGroomRequest.AppendLine("<map in-pid=\"-1\" type=\"-1\" />");
createGroomRequest.AppendLine("</input>");
createGroomRequest.AppendLine("</redundancy>");
createGroomRequest.AppendLine("</prog-groom>");
createGroomRequest.AppendLine("</action-defs>");
createGroomRequest.AppendLine("</request>");protocol.SetParameter(Parameter.splicexmlreq, Convert.ToString(createGroomRequest));
protocol.CheckTrigger(9); // make spliceprotocol.Log(Convert.ToString(createGroomRequest));
}
catch (Exception e)
{
protocol.Log($"Groom failed " + e.StackTrace);
}
}private class DeviceData
{
public object Manager { get; set; }public object Farmer { get; set; }
public object SID { get; set; }
public object DeviceVersion { get; set; }
}private class InputProgramData
{
public object Name { get; set; }public object Line_Pr { get; set; }
public object ID_Pr { get; set; }
public object ProgramNumber_Pr { get; set; }
public object Line_Bkp { get; set; }
public object ID_Bkp { get; set; }
public object ProgramNumber_Bkp { get; set; }
public object Index { get; set; }
}private class OutputProgramData
{
public object Name { get; set; }public object Line { get; set; }
public object ID { get; set; }
public object ProgramNumber { get; set; }
public object Index { get; set; }
}
}
Hi Donnell, you want that your QAction triggers everytime you make a set on a cell of parameter 9106? Even if the value doesn't change?