feat: add JoeAppEngine OPC UA nodes, fix DCL auto-reconnect and quality push

- 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
This commit is contained in:
Joseph Doherty
2026-03-19 13:27:54 -04:00
parent ffdda51990
commit 7740a3bcf9
70 changed files with 2684 additions and 541 deletions

View File

@@ -6,18 +6,18 @@ namespace ScadaLink.CLI.Commands;
public static class DeployCommands
{
public static Command Build(Option<string> contactPointsOption, Option<string> formatOption)
public static Command Build(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var command = new Command("deploy") { Description = "Deployment operations" };
command.Add(BuildInstance(contactPointsOption, formatOption));
command.Add(BuildArtifacts(contactPointsOption, formatOption));
command.Add(BuildStatus(contactPointsOption, formatOption));
command.Add(BuildInstance(contactPointsOption, formatOption, usernameOption, passwordOption));
command.Add(BuildArtifacts(contactPointsOption, formatOption, usernameOption, passwordOption));
command.Add(BuildStatus(contactPointsOption, formatOption, usernameOption, passwordOption));
return command;
}
private static Command BuildInstance(Option<string> contactPointsOption, Option<string> formatOption)
private static Command BuildInstance(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var idOption = new Option<int>("--id") { Description = "Instance ID", Required = true };
var cmd = new Command("instance") { Description = "Deploy a single instance" };
@@ -26,12 +26,12 @@ public static class DeployCommands
{
var id = result.GetValue(idOption);
return await CommandHelpers.ExecuteCommandAsync(
result, contactPointsOption, formatOption, new MgmtDeployInstanceCommand(id));
result, contactPointsOption, formatOption, usernameOption, passwordOption, new MgmtDeployInstanceCommand(id));
});
return cmd;
}
private static Command BuildArtifacts(Option<string> contactPointsOption, Option<string> formatOption)
private static Command BuildArtifacts(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var siteIdOption = new Option<int?>("--site-id") { Description = "Target site ID (all sites if omitted)" };
var cmd = new Command("artifacts") { Description = "Deploy artifacts to site(s)" };
@@ -40,12 +40,12 @@ public static class DeployCommands
{
var siteId = result.GetValue(siteIdOption);
return await CommandHelpers.ExecuteCommandAsync(
result, contactPointsOption, formatOption, new MgmtDeployArtifactsCommand(siteId));
result, contactPointsOption, formatOption, usernameOption, passwordOption, new MgmtDeployArtifactsCommand(siteId));
});
return cmd;
}
private static Command BuildStatus(Option<string> contactPointsOption, Option<string> formatOption)
private static Command BuildStatus(Option<string> contactPointsOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
{
var instanceIdOption = new Option<int?>("--instance-id") { Description = "Filter by instance ID" };
var statusOption = new Option<string?>("--status") { Description = "Filter by status" };
@@ -66,7 +66,7 @@ public static class DeployCommands
var page = result.GetValue(pageOption);
var pageSize = result.GetValue(pageSizeOption);
return await CommandHelpers.ExecuteCommandAsync(
result, contactPointsOption, formatOption,
result, contactPointsOption, formatOption, usernameOption, passwordOption,
new QueryDeploymentsCommand(instanceId, status, page, pageSize));
});
return cmd;