7740a3bcf9
- Add JoeAppEngine folder to OPC UA nodes.json (BTCS, AlarmCntsBySeverity, Scheduler/ScanTime) - Fix DataConnectionActor: capture Self in PreStart for use from non-actor threads, preventing Self.Tell failure in Disconnected event handler - Implement InstanceActor.HandleConnectionQualityChanged to mark attributes Bad on disconnect - Fix LmxFakeProxy TagMapper to serialize arrays as JSON instead of "System.Int32[]" - Allow DataType and DataSourceReference updates in TemplateService.UpdateAttributeAsync - Update test_infra_opcua.md with JoeAppEngine documentation
418 lines
22 KiB
C#
418 lines
22 KiB
C#
using System.CommandLine;
|
|
using System.CommandLine.Parsing;
|
|
using ScadaLink.Commons.Messages.Management;
|
|
|
|
namespace ScadaLink.CLI.Commands;
|
|
|
|
public static class TemplateCommands
|
|
{
|
|
public static Command Build(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var command = new Command("template") { Description = "Manage templates" };
|
|
|
|
command.Add(BuildList(contactPointsOption, formatOption, usernameOption, passwordOption));
|
|
command.Add(BuildGet(contactPointsOption, formatOption, usernameOption, passwordOption));
|
|
command.Add(BuildCreate(contactPointsOption, formatOption, usernameOption, passwordOption));
|
|
command.Add(BuildUpdate(contactPointsOption, formatOption, usernameOption, passwordOption));
|
|
command.Add(BuildValidate(contactPointsOption, formatOption, usernameOption, passwordOption));
|
|
command.Add(BuildDelete(contactPointsOption, formatOption, usernameOption, passwordOption));
|
|
command.Add(BuildAttribute(contactPointsOption, formatOption, usernameOption, passwordOption));
|
|
command.Add(BuildAlarm(contactPointsOption, formatOption, usernameOption, passwordOption));
|
|
command.Add(BuildScript(contactPointsOption, formatOption, usernameOption, passwordOption));
|
|
command.Add(BuildComposition(contactPointsOption, formatOption, usernameOption, passwordOption));
|
|
|
|
return command;
|
|
}
|
|
|
|
private static Command BuildList(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var cmd = new Command("list") { Description = "List all templates" };
|
|
cmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption, new ListTemplatesCommand());
|
|
});
|
|
return cmd;
|
|
}
|
|
|
|
private static Command BuildGet(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var idOption = new Option<int>("--id") { Description = "Template ID", Required = true };
|
|
var cmd = new Command("get") { Description = "Get a template by ID" };
|
|
cmd.Add(idOption);
|
|
cmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var id = result.GetValue(idOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption, new GetTemplateCommand(id));
|
|
});
|
|
return cmd;
|
|
}
|
|
|
|
private static Command BuildCreate(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var nameOption = new Option<string>("--name") { Description = "Template name", Required = true };
|
|
var descOption = new Option<string?>("--description") { Description = "Template description" };
|
|
var parentOption = new Option<int?>("--parent-id") { Description = "Parent template ID" };
|
|
|
|
var cmd = new Command("create") { Description = "Create a new template" };
|
|
cmd.Add(nameOption);
|
|
cmd.Add(descOption);
|
|
cmd.Add(parentOption);
|
|
cmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var name = result.GetValue(nameOption)!;
|
|
var desc = result.GetValue(descOption);
|
|
var parentId = result.GetValue(parentOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new CreateTemplateCommand(name, desc, parentId));
|
|
});
|
|
return cmd;
|
|
}
|
|
|
|
private static Command BuildUpdate(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var idOption = new Option<int>("--id") { Description = "Template ID", Required = true };
|
|
var nameOption = new Option<string>("--name") { Description = "Template name", Required = true };
|
|
var descOption = new Option<string?>("--description") { Description = "Template description" };
|
|
var parentOption = new Option<int?>("--parent-id") { Description = "Parent template ID" };
|
|
|
|
var cmd = new Command("update") { Description = "Update a template" };
|
|
cmd.Add(idOption);
|
|
cmd.Add(nameOption);
|
|
cmd.Add(descOption);
|
|
cmd.Add(parentOption);
|
|
cmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var id = result.GetValue(idOption);
|
|
var name = result.GetValue(nameOption)!;
|
|
var desc = result.GetValue(descOption);
|
|
var parentId = result.GetValue(parentOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new UpdateTemplateCommand(id, name, desc, parentId));
|
|
});
|
|
return cmd;
|
|
}
|
|
|
|
private static Command BuildValidate(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var idOption = new Option<int>("--id") { Description = "Template ID", Required = true };
|
|
var cmd = new Command("validate") { Description = "Validate a template" };
|
|
cmd.Add(idOption);
|
|
cmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var id = result.GetValue(idOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption, new ValidateTemplateCommand(id));
|
|
});
|
|
return cmd;
|
|
}
|
|
|
|
private static Command BuildDelete(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var idOption = new Option<int>("--id") { Description = "Template ID", Required = true };
|
|
var cmd = new Command("delete") { Description = "Delete a template" };
|
|
cmd.Add(idOption);
|
|
cmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
var id = result.GetValue(idOption);
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption, new DeleteTemplateCommand(id));
|
|
});
|
|
return cmd;
|
|
}
|
|
|
|
private static Command BuildAttribute(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var group = new Command("attribute") { Description = "Manage template attributes" };
|
|
|
|
var templateIdOption = new Option<int>("--template-id") { Description = "Template ID", Required = true };
|
|
var nameOption = new Option<string>("--name") { Description = "Attribute name", Required = true };
|
|
var dataTypeOption = new Option<string>("--data-type") { Description = "Data type", Required = true };
|
|
var valueOption = new Option<string?>("--value") { Description = "Default value" };
|
|
var descOption = new Option<string?>("--description") { Description = "Description" };
|
|
var sourceOption = new Option<string?>("--data-source") { Description = "Data source reference" };
|
|
var lockedOption = new Option<bool>("--locked") { Description = "Lock status" };
|
|
lockedOption.DefaultValueFactory = _ => false;
|
|
|
|
var addCmd = new Command("add") { Description = "Add an attribute to a template" };
|
|
addCmd.Add(templateIdOption);
|
|
addCmd.Add(nameOption);
|
|
addCmd.Add(dataTypeOption);
|
|
addCmd.Add(valueOption);
|
|
addCmd.Add(descOption);
|
|
addCmd.Add(sourceOption);
|
|
addCmd.Add(lockedOption);
|
|
addCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new AddTemplateAttributeCommand(
|
|
result.GetValue(templateIdOption),
|
|
result.GetValue(nameOption)!,
|
|
result.GetValue(dataTypeOption)!,
|
|
result.GetValue(valueOption),
|
|
result.GetValue(descOption),
|
|
result.GetValue(sourceOption),
|
|
result.GetValue(lockedOption)));
|
|
});
|
|
group.Add(addCmd);
|
|
|
|
var updateIdOption = new Option<int>("--id") { Description = "Attribute ID", Required = true };
|
|
var updateNameOption = new Option<string>("--name") { Description = "Attribute name", Required = true };
|
|
var updateDataTypeOption = new Option<string>("--data-type") { Description = "Data type", Required = true };
|
|
var updateValueOption = new Option<string?>("--value") { Description = "Default value" };
|
|
var updateDescOption = new Option<string?>("--description") { Description = "Description" };
|
|
var updateSourceOption = new Option<string?>("--data-source") { Description = "Data source reference" };
|
|
var updateLockedOption = new Option<bool>("--locked") { Description = "Lock status" };
|
|
updateLockedOption.DefaultValueFactory = _ => false;
|
|
|
|
var updateCmd = new Command("update") { Description = "Update a template attribute" };
|
|
updateCmd.Add(updateIdOption);
|
|
updateCmd.Add(updateNameOption);
|
|
updateCmd.Add(updateDataTypeOption);
|
|
updateCmd.Add(updateValueOption);
|
|
updateCmd.Add(updateDescOption);
|
|
updateCmd.Add(updateSourceOption);
|
|
updateCmd.Add(updateLockedOption);
|
|
updateCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new UpdateTemplateAttributeCommand(
|
|
result.GetValue(updateIdOption),
|
|
result.GetValue(updateNameOption)!,
|
|
result.GetValue(updateDataTypeOption)!,
|
|
result.GetValue(updateValueOption),
|
|
result.GetValue(updateDescOption),
|
|
result.GetValue(updateSourceOption),
|
|
result.GetValue(updateLockedOption)));
|
|
});
|
|
group.Add(updateCmd);
|
|
|
|
var deleteIdOption = new Option<int>("--id") { Description = "Attribute ID", Required = true };
|
|
var deleteCmd = new Command("delete") { Description = "Delete a template attribute" };
|
|
deleteCmd.Add(deleteIdOption);
|
|
deleteCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new DeleteTemplateAttributeCommand(result.GetValue(deleteIdOption)));
|
|
});
|
|
group.Add(deleteCmd);
|
|
|
|
return group;
|
|
}
|
|
|
|
private static Command BuildAlarm(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var group = new Command("alarm") { Description = "Manage template alarms" };
|
|
|
|
var templateIdOption = new Option<int>("--template-id") { Description = "Template ID", Required = true };
|
|
var nameOption = new Option<string>("--name") { Description = "Alarm name", Required = true };
|
|
var triggerTypeOption = new Option<string>("--trigger-type") { Description = "Trigger type", Required = true };
|
|
var priorityOption = new Option<int>("--priority") { Description = "Alarm priority", Required = true };
|
|
var descOption = new Option<string?>("--description") { Description = "Description" };
|
|
var triggerConfigOption = new Option<string?>("--trigger-config") { Description = "Trigger configuration JSON" };
|
|
var lockedOption = new Option<bool>("--locked") { Description = "Lock status" };
|
|
lockedOption.DefaultValueFactory = _ => false;
|
|
|
|
var addCmd = new Command("add") { Description = "Add an alarm to a template" };
|
|
addCmd.Add(templateIdOption);
|
|
addCmd.Add(nameOption);
|
|
addCmd.Add(triggerTypeOption);
|
|
addCmd.Add(priorityOption);
|
|
addCmd.Add(descOption);
|
|
addCmd.Add(triggerConfigOption);
|
|
addCmd.Add(lockedOption);
|
|
addCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new AddTemplateAlarmCommand(
|
|
result.GetValue(templateIdOption),
|
|
result.GetValue(nameOption)!,
|
|
result.GetValue(triggerTypeOption)!,
|
|
result.GetValue(priorityOption)!,
|
|
result.GetValue(descOption),
|
|
result.GetValue(triggerConfigOption),
|
|
result.GetValue(lockedOption)));
|
|
});
|
|
group.Add(addCmd);
|
|
|
|
var updateIdOption = new Option<int>("--id") { Description = "Alarm ID", Required = true };
|
|
var updateNameOption = new Option<string>("--name") { Description = "Alarm name", Required = true };
|
|
var updateTriggerTypeOption = new Option<string>("--trigger-type") { Description = "Trigger type", Required = true };
|
|
var updatePriorityOption = new Option<int>("--priority") { Description = "Alarm priority", Required = true };
|
|
var updateDescOption = new Option<string?>("--description") { Description = "Description" };
|
|
var updateTriggerConfigOption = new Option<string?>("--trigger-config") { Description = "Trigger configuration JSON" };
|
|
var updateLockedOption = new Option<bool>("--locked") { Description = "Lock status" };
|
|
updateLockedOption.DefaultValueFactory = _ => false;
|
|
|
|
var updateCmd = new Command("update") { Description = "Update a template alarm" };
|
|
updateCmd.Add(updateIdOption);
|
|
updateCmd.Add(updateNameOption);
|
|
updateCmd.Add(updateTriggerTypeOption);
|
|
updateCmd.Add(updatePriorityOption);
|
|
updateCmd.Add(updateDescOption);
|
|
updateCmd.Add(updateTriggerConfigOption);
|
|
updateCmd.Add(updateLockedOption);
|
|
updateCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new UpdateTemplateAlarmCommand(
|
|
result.GetValue(updateIdOption),
|
|
result.GetValue(updateNameOption)!,
|
|
result.GetValue(updateTriggerTypeOption)!,
|
|
result.GetValue(updatePriorityOption)!,
|
|
result.GetValue(updateDescOption),
|
|
result.GetValue(updateTriggerConfigOption),
|
|
result.GetValue(updateLockedOption)));
|
|
});
|
|
group.Add(updateCmd);
|
|
|
|
var deleteIdOption = new Option<int>("--id") { Description = "Alarm ID", Required = true };
|
|
var deleteCmd = new Command("delete") { Description = "Delete a template alarm" };
|
|
deleteCmd.Add(deleteIdOption);
|
|
deleteCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new DeleteTemplateAlarmCommand(result.GetValue(deleteIdOption)));
|
|
});
|
|
group.Add(deleteCmd);
|
|
|
|
return group;
|
|
}
|
|
|
|
private static Command BuildScript(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var group = new Command("script") { Description = "Manage template scripts" };
|
|
|
|
var templateIdOption = new Option<int>("--template-id") { Description = "Template ID", Required = true };
|
|
var nameOption = new Option<string>("--name") { Description = "Script name", Required = true };
|
|
var codeOption = new Option<string>("--code") { Description = "Script code", Required = true };
|
|
var triggerTypeOption = new Option<string>("--trigger-type") { Description = "Trigger type", Required = true };
|
|
var triggerConfigOption = new Option<string?>("--trigger-config") { Description = "Trigger configuration JSON" };
|
|
var lockedOption = new Option<bool>("--locked") { Description = "Lock status" };
|
|
lockedOption.DefaultValueFactory = _ => false;
|
|
|
|
var paramsOption = new Option<string?>("--parameters") { Description = "Parameter definitions JSON" };
|
|
var returnOption = new Option<string?>("--return-def") { Description = "Return definition JSON" };
|
|
|
|
var addCmd = new Command("add") { Description = "Add a script to a template" };
|
|
addCmd.Add(templateIdOption);
|
|
addCmd.Add(nameOption);
|
|
addCmd.Add(codeOption);
|
|
addCmd.Add(triggerTypeOption);
|
|
addCmd.Add(triggerConfigOption);
|
|
addCmd.Add(lockedOption);
|
|
addCmd.Add(paramsOption);
|
|
addCmd.Add(returnOption);
|
|
addCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new AddTemplateScriptCommand(
|
|
result.GetValue(templateIdOption),
|
|
result.GetValue(nameOption)!,
|
|
result.GetValue(codeOption)!,
|
|
result.GetValue(triggerTypeOption)!,
|
|
result.GetValue(triggerConfigOption),
|
|
result.GetValue(lockedOption),
|
|
result.GetValue(paramsOption),
|
|
result.GetValue(returnOption)));
|
|
});
|
|
group.Add(addCmd);
|
|
|
|
var updateIdOption = new Option<int>("--id") { Description = "Script ID", Required = true };
|
|
var updateNameOption = new Option<string>("--name") { Description = "Script name", Required = true };
|
|
var updateCodeOption = new Option<string>("--code") { Description = "Script code", Required = true };
|
|
var updateTriggerTypeOption = new Option<string>("--trigger-type") { Description = "Trigger type", Required = true };
|
|
var updateTriggerConfigOption = new Option<string?>("--trigger-config") { Description = "Trigger configuration JSON" };
|
|
var updateLockedOption = new Option<bool>("--locked") { Description = "Lock status" };
|
|
updateLockedOption.DefaultValueFactory = _ => false;
|
|
|
|
var updateParamsOption = new Option<string?>("--parameters") { Description = "Parameter definitions JSON" };
|
|
var updateReturnOption = new Option<string?>("--return-def") { Description = "Return definition JSON" };
|
|
|
|
var updateCmd = new Command("update") { Description = "Update a template script" };
|
|
updateCmd.Add(updateIdOption);
|
|
updateCmd.Add(updateNameOption);
|
|
updateCmd.Add(updateCodeOption);
|
|
updateCmd.Add(updateTriggerTypeOption);
|
|
updateCmd.Add(updateTriggerConfigOption);
|
|
updateCmd.Add(updateLockedOption);
|
|
updateCmd.Add(updateParamsOption);
|
|
updateCmd.Add(updateReturnOption);
|
|
updateCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new UpdateTemplateScriptCommand(
|
|
result.GetValue(updateIdOption),
|
|
result.GetValue(updateNameOption)!,
|
|
result.GetValue(updateCodeOption)!,
|
|
result.GetValue(updateTriggerTypeOption)!,
|
|
result.GetValue(updateTriggerConfigOption),
|
|
result.GetValue(updateLockedOption),
|
|
result.GetValue(updateParamsOption),
|
|
result.GetValue(updateReturnOption)));
|
|
});
|
|
group.Add(updateCmd);
|
|
|
|
var deleteIdOption = new Option<int>("--id") { Description = "Script ID", Required = true };
|
|
var deleteCmd = new Command("delete") { Description = "Delete a template script" };
|
|
deleteCmd.Add(deleteIdOption);
|
|
deleteCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new DeleteTemplateScriptCommand(result.GetValue(deleteIdOption)));
|
|
});
|
|
group.Add(deleteCmd);
|
|
|
|
return group;
|
|
}
|
|
|
|
private static Command BuildComposition(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
|
|
{
|
|
var group = new Command("composition") { Description = "Manage template compositions" };
|
|
|
|
var templateIdOption = new Option<int>("--template-id") { Description = "Template ID", Required = true };
|
|
var instanceNameOption = new Option<string>("--instance-name") { Description = "Composed instance name", Required = true };
|
|
var composedTemplateIdOption = new Option<int>("--composed-template-id") { Description = "Composed template ID", Required = true };
|
|
|
|
var addCmd = new Command("add") { Description = "Add a composition to a template" };
|
|
addCmd.Add(templateIdOption);
|
|
addCmd.Add(instanceNameOption);
|
|
addCmd.Add(composedTemplateIdOption);
|
|
addCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new AddTemplateCompositionCommand(
|
|
result.GetValue(templateIdOption),
|
|
result.GetValue(instanceNameOption)!,
|
|
result.GetValue(composedTemplateIdOption)));
|
|
});
|
|
group.Add(addCmd);
|
|
|
|
var deleteIdOption = new Option<int>("--id") { Description = "Composition ID", Required = true };
|
|
var deleteCmd = new Command("delete") { Description = "Delete a template composition" };
|
|
deleteCmd.Add(deleteIdOption);
|
|
deleteCmd.SetAction(async (ParseResult result) =>
|
|
{
|
|
return await CommandHelpers.ExecuteCommandAsync(
|
|
result, contactPointsOption, formatOption, usernameOption, passwordOption,
|
|
new DeleteTemplateCompositionCommand(result.GetValue(deleteIdOption)));
|
|
});
|
|
group.Add(deleteCmd);
|
|
|
|
return group;
|
|
}
|
|
}
|