Hi, I don’t understand your question. Can you give more detail on what are you asking? I can provide you with a test example of using a custom templates task, but I am not sure that is what you want.
[TestMethod]
public void DriverCommandGetCurrentDefinitionsCustomTemplate()
{
IoTTestOrchestrator.MockSystem.PluginMain system = (testContext.System as IoTTestOrchestrator.MockSystem.PluginMain);
system.WaitForAllComunicating(40);
var controllerInstance = testContext.Instances["Controller"] as IControllerInstanceContext;
var hasBeenCalled = false;
Exception? callbackException = null;
controllerInstance.SystemEvent("Cmf.Test.DF.DriverCommand.GetCurrentDefinition.CustomTemplate.Request", new
{
message = "Activation"
},
SendType.SendRequest,
(evt) =>
{
try
{
JObject payload = JObject.Parse(evt);
JObject json = payload["reply"] as JObject ?? payload;
var properties = (JArray)json["properties"]!;
var events = (JArray)json["events"]!;
var commands = (JArray)json["commands"]!;
var customProperty = properties.Children<JObject>().SingleOrDefault(p => p["name"]?.ToString() == "CurrentDefinitionsCustomProperty");
Assert.IsNotNull(customProperty, "Expected custom property to be included in the current definitions reply.");
Assert.AreEqual("AccessTime", customProperty!["deviceId"]?.ToString());
Assert.AreEqual("AccessTime", customProperty["extendedData"]?["propertyType"]?.ToString());
var customEvent = events.Children<JObject>().SingleOrDefault(e => e["name"]?.ToString() == "CurrentDefinitionsCustomEvent");
Assert.IsNotNull(customEvent, "Expected custom event to be included in the current definitions reply.");
Assert.AreEqual("DeletedFile", customEvent!["deviceId"]?.ToString());
Assert.AreEqual("DeletedFile", customEvent["extendedData"]?["eventTrigger"]?.ToString());
Assert.AreEqual("CurrentDefinitionsCustomProperty", customEvent["properties"]?.First?["name"]?.ToString());
Assert.AreEqual("None", customEvent["properties"]?.First?["extendedData"]?["identifierType"]?.ToString());
var customCommand = commands.Children<JObject>().SingleOrDefault(c => c["name"]?.ToString() == "CurrentDefinitionsCustomCommand");
Assert.IsNotNull(customCommand, "Expected custom command to be included in the current definitions reply.");
Assert.AreEqual("Exists", customCommand!["deviceId"]?.ToString());
Assert.AreEqual("Exists", customCommand["extendedData"]?["commandType"]?.ToString());
Assert.AreEqual("CurrentDefinitionsCustomParameter", customCommand["parameters"]?.First?["name"]?.ToString());
Assert.AreEqual("CurrentDefinitionsCustomDefaultValue", customCommand["parameters"]?.First?["defaultValue"]?.ToString());
Assert.AreEqual("CurrentDefinitionsCustomParameterSource", customCommand["parameters"]?.First?["extendedData"]?["parameterSource"]?.ToString());
hasBeenCalled = true;
}
catch (Exception ex)
{
callbackException = ex;
}
});
testScenario.Utilities.WaitFor(20, "It was never invoked", () =>
{
return hasBeenCalled || callbackException != null;
});
if (callbackException != null)
{
throw new AssertFailedException($"Reply validation failed: {callbackException.Message}", callbackException);
}
}
{
"tasks": [
{
"id": "task_101",
"reference": {
"name": "customTemplates",
"package": {
"name": "@criticalmanufacturing/connect-iot-controller-engine-core-tasks",
"version": "12.0.0-dev"
}
},
"settings": {
"values": [
{
"name": "CurrentDefinitionsCustomTemplate",
"description": "Adds custom definitions to validate CurrentDefinitions reply",
"json": {
"properties": [
{
"Name": "CurrentDefinitionsCustomProperty",
"DevicePropertyId": "CurrentDefinitionsCustomProperty",
"DataType": "String",
"AutomationProtocolDataType": "String",
"IsReadable": true,
"IsWritable": false,
"ExtendedData": {
"propertyType": "AccessTime"
}
}
],
"events": [
{
"Name": "CurrentDefinitionsCustomEvent",
"DeviceEventId": "CurrentDefinitionsCustomEvent",
"IsEnabled": true,
"ExtendedData": {
"eventTrigger": "DeletedFile"
},
"EventProperties": [
{
"Property": "CurrentDefinitionsCustomProperty",
"Order": 1,
"ExtendedData": {
"identifierType": "None"
}
}
]
}
],
"commands": [
{
"Name": "CurrentDefinitionsCustomCommand",
"DeviceCommandId": "CurrentDefinitionsCustomCommand",
"ExtendedData": {
"commandType": "Exists"
},
"CommandParameters": [
{
"Name": "CurrentDefinitionsCustomParameter",
"Order": 1,
"DataType": "String",
"AutomationProtocolDataType": "String",
"DefaultValue": "CurrentDefinitionsCustomDefaultValue",
"IsMandatory": false,
"ExtendedData": {
"parameterSource": "CurrentDefinitionsCustomParameterSource"
}
}
]
}
]
}
}
],
"___cmf___name": "Custom Driver Definition"
},
"driver": "Handler"
},
{
"id": "task_102",
"reference": {
"name": "driverCommand",
"package": {
"name": "@criticalmanufacturing/connect-iot-controller-engine-core-tasks",
"version": "12.0.0-dev"
}
},
"settings": {
"command": "CurrentDefinitions",
"___cmf___name": "Driver Command"
},
"driver": "Handler"
},
{
"id": "task_103",
"reference": {
"name": "systemActionReply",
"package": {
"name": "@criticalmanufacturing/connect-iot-controller-engine-core-tasks",
"version": "12.0.0-dev"
}
},
"settings": {
"defaultReply": {},
"___cmf___name": "System Action Reply"
}
},
{
"id": "task_104",
"reference": {
"name": "systemActionListener",
"package": {
"name": "@criticalmanufacturing/connect-iot-controller-engine-core-tasks",
"version": "12.0.0-dev"
}
},
"settings": {
"autoEnable": true,
"actionGroup": "Cmf.Test.DF.DriverCommand.GetCurrentDefinition.CustomTemplate.Request",
"replyTimeout": 60000,
"___cmf___name": "System Action Listener"
}
}
],
"converters": [],
"links": [
{
"id": "link_101",
"sourceId": "task_104",
"targetId": "task_101",
"inputName": "activate",
"outputName": "success"
},
{
"id": "link_102",
"sourceId": "task_101",
"targetId": "task_102",
"inputName": "activate",
"outputName": "success"
},
{
"id": "link_103",
"sourceId": "task_102",
"targetId": "task_103",
"inputName": "reply",
"outputName": "reply"
},
{
"id": "link_104",
"sourceId": "task_102",
"targetId": "task_103",
"inputName": "activate",
"outputName": "success"
}
],
"layout": {
"general": {
"color": null,
"notes": []
},
"drawers": {
"DIAGRAM": {
"tasks": {
"task_101": {
"collapsed": false,
"position": {
"x": 619,
"y": 136
},
"outdated": false
},
"task_102": {
"collapsed": false,
"position": {
"x": 1157,
"y": 136
},
"outdated": false
},
"task_103": {
"collapsed": false,
"position": {
"x": 1703,
"y": 194
},
"outdated": false
},
"task_104": {
"collapsed": false,
"position": {
"x": 104,
"y": 111
},
"outdated": false
}
},
"links": {
"link_101": {
"vertices": []
},
"link_102": {
"vertices": []
},
"link_103": {
"vertices": []
},
"link_104": {
"vertices": []
}
},
"notes": {},
"pan": {
"x": 0,
"y": 0
},
"zoom": 0.58
}
}
}
}