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; }
}
}
the qaction has a check for a specific value for the full qaction to complete, im only looking to have the action fire if there is a value change
Hi Donnell, sorry to insist, but it's still not clear to me when you the QAction should be triggered.
Is it because of the set of parameter 9106 that is done in the last part of the automation screenshot?
If so, you want to trigger every time that value changes correct?
yes that is correct. i want to run the qaction whenever the 9106 value is changed. i did managed to figure out what the issue was though. look like the "force execute" option on my Action group was causing the inconsistent results. after changing it to "execute next" ive had no problems.
Glad that it worked out
I get the impression that this question has already been answered in the comments. If this is indeed the case, could you select this answer to indicate that the question can be closed and no further follow-up is needed?
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?