Hi All,
I am attempting to determine the expected payload for a SetDataMinerInfoMessage message, the current NotifyType I am interested in replicating is NT_FILL_ARRAY_WITH_COLUMN.
This call is intended to be called with the NotifyProtocol method within a protocol, but this option is not available for Automation Scripts. As I am unable to find an equivalent alternative for automation scripts the next best thing would be to use the underlying SetDataMinerInfoMessage call instead.
The trouble with SetDataMinerInfoMessage is that it contains many fields: What, IInfo1, IInfo2, bInfo1, bInfo2, StrInfo1, StrInfo2, Uia1, Uia2, Puia1, Puia2, Sa1, Sa2, Psa1, Psa2, UiaNotifier, ElementID, Var1 and Var2. Depending on the call you make the fields that are required vary massively with little consistency between each call.
I have used this call many times and managed to work out the expected payload by following a cube session in the client test tool. This works well for calls made by the client, but it doesn't appear to work for QActions. If I follow SLManagedScripting, I can see other SLNet messages such as GetPartialTableMessage, but not any of the SetDataMinerInfoMessage.
This leads me back to my goal of working out NT_FILL_ARRAY_WITH_COLUMN which can only natively invoke in a QAction. So my question is, is there a way to sniff out SetDataMinerInfoMessage calls?
Alternatively, I would settle for documentation breaking down each NotifyType with the expected payload for its corresponding SetDataMinerInfoMessage. But I imagine this is not likely something you would want to provide to customers as it's not intended to be called directly.
Any help will be greatly appreciated.
Thanks
With guidance from Floris's reply, I have managed to achieve setting a column from an Automation Script. Below are some methods to hopefully help someone in the future.
Basic Method
SetColumn(engine, 127001, 1234, 1000, 1005, new[] { "1", "2" }, new object[] { "Hello", "World" });
public void SetColumn(Engine engine, int dataMinerId, int elementId, int tablePid, int columnPid, string[] keys, object[] values)
{
if (keys == null || keys.Length == 0)
{
throw new ArgumentException("Cannot be null or empty.", "keys");
}if (values == null || values.Length == 0)
{
throw new ArgumentException("Cannot be null or empty.", "values");
}var primaryKeys = keys.Cast<object>().ToArray();
var ids = new object[] { dataMinerId, elementId, tablePid, columnPid };
var tableData = new object[] { primaryKeys, values };try
{
var message = new SetDataMinerInfoMessage()
{
Var1 = ids,
Var2 = tableData,
What = (int)NotifyType.NT_FILL_ARRAY_WITH_COLUMN_ONLY_UPDATES,
};engine.SendSLNetSingleResponseMessage(message);
}
catch (DataMinerCOMException e)
{
if (e.ErrorCode == -2147220718 || e.ErrorCode == -2147220916)
{
// 0x80040312, Unknown destination DataMiner specified.
// 0x8004024C, SL_NO_SUCH_ELEMENT, "The element is unknown."
throw new ArgumentNullException(FormattableString.Invariant($"Element with DMA ID '{dataMinerId}' and element ID '{elementId}' was not found."), e);
}
else if (e.ErrorCode == -2147220959)
{
// 0x80040221, SL_INVALID_DATA, "Invalid data".
throw new ArgumentNullException(FormattableString.Invariant($"Invalid data - element: '{dataMinerId}/{elementId}', table ID: '{tablePid}', column ID: '{columnPid}', data: {JsonConvert.SerializeObject(tableData)}"), e);
}
else
{
throw;
}
}
}
IDms Extension Method
var dms = engine.GetDms();
var element = dms.GetElement("Test Protocol");
var table = element.GetTable(1000);
var column = table.GetColumn<string>(1005);
column.SetValues(new[] { "1", "2" }, new object[] { "Hello", "World" });
public static class IDmsExtensions
{
public static void SetValues(this IDmsColumn column, string[] keys, object[] values)
{
if (keys == null || keys.Length == 0)
{
throw new ArgumentException("Cannot be null or empty.", "keys");
}if (values == null || values.Length == 0)
{
throw new ArgumentException("Cannot be null or empty.", "values");
}var table = column.Table;
var element = table.Element;var primaryKeys = keys.Cast<object>().ToArray();
var ids = new object[] { element.AgentId, element.Id, table.Id, column.Id };
var tableData = new object[] { primaryKeys, values };try
{
var message = new SetDataMinerInfoMessage()
{
Var1 = ids,
Var2 = tableData,
What = (int)NotifyType.NT_FILL_ARRAY_WITH_COLUMN_ONLY_UPDATES,
};element.Host.Dms.Communication.SendSingleResponseMessage(message);
}
catch (DataMinerCOMException e)
{
if (e.ErrorCode == -2147220718 || e.ErrorCode == -2147220916)
{
// 0x80040312, Unknown destination DataMiner specified.
// 0x8004024C, SL_NO_SUCH_ELEMENT, "The element is unknown."
throw new ElementNotFoundException(element.DmsElementId, e);
}
else if (e.ErrorCode == -2147220959)
{
// 0x80040221, SL_INVALID_DATA, "Invalid data".
var message = FormattableString.Invariant($"Invalid data - element: '{element.DmsElementId.Value}', table ID: '{table.Id}', column ID: '{column.Id}', data: {JsonConvert.SerializeObject(tableData)}");
throw new IncorrectDataException(message);
}
else
{
throw;
}
}
}
}