Skip to content

Commit

Permalink
Fix pn.json generation (#186)
Browse files Browse the repository at this point in the history
* Fix UseSecurity

* Update nugets

* Update version

* Add and use NodeIdTypePrefix

* Fix boiler by using NodeIdTypePrefix

* Fix D-GUID by using NodeIdTypePrefix

* Cosmetic

* Add plugin nodes helper

* Fix opaque by using NodeIdTypePrefix
  • Loading branch information
luiscantero authored Nov 10, 2022
1 parent 48097b9 commit f4ae203
Show file tree
Hide file tree
Showing 17 changed files with 217 additions and 181 deletions.
45 changes: 45 additions & 0 deletions src/Helpers/PluginNodesHelpers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

namespace OpcPlc.Helpers;

using Opc.Ua;
using OpcPlc.PluginNodes.Models;
using System;

/// <summary>
/// Helper class for plugin nodes.
/// </summary>
public class PluginNodesHelpers
{
/// <summary>
/// Get node with correct type prefix, id, namespace, and intervals.
/// </summary>
public static NodeWithIntervals GetNodeWithIntervals(NodeId nodeId, PlcNodeManager plcNodeManager)
{
ExpandedNodeId expandedNodeId = NodeId.ToExpandedNodeId(nodeId, plcNodeManager.Server.NamespaceUris);

return new NodeWithIntervals
{
NodeId = expandedNodeId.IdType == IdType.Opaque
? Convert.ToBase64String((byte[])expandedNodeId.Identifier)
: expandedNodeId.Identifier.ToString(),
NodeIdTypePrefix = GetTypePrefix(expandedNodeId.IdType),
Namespace = expandedNodeId.NamespaceUri,
};
}

/// <summary>
/// Get a single lowercase character that represents the type of the node.
/// </summary>
/// <exception cref="ArgumentOutOfRangeException"></exception>
private static string GetTypePrefix(IdType idType)
{
return idType switch
{
IdType.Numeric => "i",
IdType.String => "s",
IdType.Guid => "g",
IdType.Opaque => "b",
_ => throw new ArgumentOutOfRangeException(nameof(idType), idType.ToString(), message: null),
};
}
}
4 changes: 2 additions & 2 deletions src/Helpers/PnJsonHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public static async Task PrintPublisherConfigJsonAsync(string pnJsonFileName, st
sb.AppendLine(Environment.NewLine + "[");
sb.AppendLine(" {");
sb.AppendLine($" \"EndpointUrl\": \"opc.tcp://{serverPath}\",");
sb.AppendLine(" \"UseSecurity\": false,");
sb.AppendLine($" \"UseSecurity\": {(!OpcApplicationConfiguration.EnableUnsecureTransport).ToString().ToLowerInvariant()},");
sb.AppendLine(" \"OpcNodes\": [");

// Print config from plugin nodes list.
Expand All @@ -41,7 +41,7 @@ public static async Task PrintPublisherConfigJsonAsync(string pnJsonFileName, st
: string.Empty;

string nodeId = JsonEncodedText.Encode(node.NodeId, JavaScriptEncoder.Default).ToString();
sb.AppendLine($" {{ \"Id\": \"nsu={node.Namespace};s={nodeId}\"{publishingInterval}{samplingInterval} }},");
sb.AppendLine($" {{ \"Id\": \"nsu={node.Namespace};{node.NodeIdTypePrefix}={nodeId}\"{publishingInterval}{samplingInterval} }},");
}
}

Expand Down
16 changes: 9 additions & 7 deletions src/PluginNodes/ComplexTypeBoilerPluginNode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace OpcPlc.PluginNodes;

using Opc.Ua;
using OpcPlc.Helpers;
using OpcPlc.PluginNodes.Models;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -87,14 +88,15 @@ private void AddNodes(FolderState methodsFolder)

SetHeaterOffMethodProperties(ref heaterOffMethod);

// Get BoilerStatus complex type variable.
var children = new List<BaseInstanceState>();
_node.GetChildren(_plcNodeManager.SystemContext, children);

// Add to node list for creation of pn.json.
Nodes = new List<NodeWithIntervals>
{
new NodeWithIntervals
{
NodeId = "Boiler",
Namespace = OpcPlc.Namespaces.OpcPlcBoiler,
},
};
{
PluginNodesHelpers.GetNodeWithIntervals(children[0].NodeId, _plcNodeManager),
};
}

/// <summary>
Expand Down
32 changes: 15 additions & 17 deletions src/PluginNodes/DeterministicGuidPluginNodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,21 @@ private void AddNodes(FolderState folder)
{
Guid id = DeterministicGuid.NewGuid();

_nodes[i] = _plcNodeManager.CreateVariableNode<uint>(
_plcNodeManager.CreateBaseVariable(
folder,
path: id,
name: id.ToString(),
new NodeId((uint)BuiltInType.UInt32),
ValueRanks.Scalar,
AccessLevels.CurrentReadOrWrite,
"Constantly increasing value",
NamespaceType.OpcPlcApplications,
defaultValue: (uint)0));

nodes.Add(new NodeWithIntervals
{
NodeId = id.ToString(),
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
});
BaseDataVariableState variable = _plcNodeManager.CreateBaseVariable(
folder,
path: id,
name: id.ToString(),
new NodeId((uint)BuiltInType.UInt32),
ValueRanks.Scalar,
AccessLevels.CurrentReadOrWrite,
"Constantly increasing value",
NamespaceType.OpcPlcApplications,
defaultValue: (uint)0);

_nodes[i] = _plcNodeManager.CreateVariableNode<uint>(variable);

// Add to node list for creation of pn.json.
nodes.Add(PluginNodesHelpers.GetNodeWithIntervals(variable.NodeId, _plcNodeManager));
}

Nodes = nodes;
Expand Down
33 changes: 16 additions & 17 deletions src/PluginNodes/DipPluginNode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace OpcPlc.PluginNodes;

using Opc.Ua;
using OpcPlc.Helpers;
using OpcPlc.PluginNodes.Models;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -67,25 +68,23 @@ public void StopSimulation()

private void AddNodes(FolderState folder)
{
_node = _plcNodeManager.CreateVariableNode<double>(
_plcNodeManager.CreateBaseVariable(
folder,
path: "DipData",
name: "DipData",
new NodeId((uint)BuiltInType.Double),
ValueRanks.Scalar,
AccessLevels.CurrentRead,
"Value with random dips",
NamespaceType.OpcPlcApplications));
BaseDataVariableState variable = _plcNodeManager.CreateBaseVariable(
folder,
path: "DipData",
name: "DipData",
new NodeId((uint)BuiltInType.Double),
ValueRanks.Scalar,
AccessLevels.CurrentRead,
"Value with random dips",
NamespaceType.OpcPlcApplications);

_node = _plcNodeManager.CreateVariableNode<double>(variable);

// Add to node list for creation of pn.json.
Nodes = new List<NodeWithIntervals>
{
new NodeWithIntervals
{
NodeId = "DipData",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
};
{
PluginNodesHelpers.GetNodeWithIntervals(variable.NodeId, _plcNodeManager),
};
}

/// <summary>
Expand Down
35 changes: 17 additions & 18 deletions src/PluginNodes/LongIdPluginNode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace OpcPlc.PluginNodes;

using Opc.Ua;
using OpcPlc.Helpers;
using OpcPlc.PluginNodes.Models;
using System.Collections.Generic;
using System.Text;
Expand Down Expand Up @@ -65,25 +66,23 @@ private void AddNodes(FolderState folder)
id.Append((char)(65 + (i % 26)));
}

_node = _plcNodeManager.CreateVariableNode<uint>(
_plcNodeManager.CreateBaseVariable(
folder,
path: id.ToString(),
name: "LongId3950",
new NodeId((uint)BuiltInType.UInt32),
ValueRanks.Scalar,
AccessLevels.CurrentReadOrWrite,
"Constantly increasing value",
NamespaceType.OpcPlcApplications,
defaultValue: (uint)0));
BaseDataVariableState variable = _plcNodeManager.CreateBaseVariable(
folder,
path: id.ToString(),
name: "LongId3950",
new NodeId((uint)BuiltInType.UInt32),
ValueRanks.Scalar,
AccessLevels.CurrentReadOrWrite,
"Constantly increasing value",
NamespaceType.OpcPlcApplications,
defaultValue: (uint)0);

_node = _plcNodeManager.CreateVariableNode<uint>(variable);

// Add to node list for creation of pn.json.
Nodes = new List<NodeWithIntervals>
{
new NodeWithIntervals
{
NodeId = id.ToString(),
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
};
{
PluginNodesHelpers.GetNodeWithIntervals(variable.NodeId, _plcNodeManager),
};
}
}
44 changes: 22 additions & 22 deletions src/PluginNodes/LongStringPluginNodes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class LongStringPluginNodes : IPluginNodes
private SimulatedVariableNode<string> _longStringIdNode50;
private SimulatedVariableNode<byte[]> _longStringIdNode100;
private SimulatedVariableNode<byte[]> _longStringIdNode200;
private readonly Random _random = new Random();
private readonly Random _random = new();

public void AddOptions(Mono.Options.OptionSet optionSet)
{
Expand Down Expand Up @@ -129,27 +129,27 @@ private void AddNodes(FolderState folder)
initialByteArray));

Nodes = new List<NodeWithIntervals>
{
new NodeWithIntervals
{
NodeId = "LongString10kB",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
new NodeWithIntervals
{
NodeId = "LongString50kB",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
new NodeWithIntervals
{
NodeId = "LongString100kB",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
new NodeWithIntervals
{
new NodeWithIntervals
{
NodeId = "LongString10kB",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
new NodeWithIntervals
{
NodeId = "LongString50kB",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
new NodeWithIntervals
{
NodeId = "LongString100kB",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
new NodeWithIntervals
{
NodeId = "LongString200kB",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
};
NodeId = "LongString200kB",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
};
}
}
1 change: 1 addition & 0 deletions src/PluginNodes/Models/NodeWithIntervals.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
public class NodeWithIntervals
{
public string NodeId { get; set; }
public string NodeIdTypePrefix { get; set; } = "s"; // Default type is string.
public string Namespace { get; set; }
public uint PublishingInterval { get; set; }
public uint SamplingInterval { get; set; }
Expand Down
33 changes: 16 additions & 17 deletions src/PluginNodes/NegTrendPluginNode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace OpcPlc.PluginNodes;

using Opc.Ua;
using OpcPlc.Helpers;
using OpcPlc.PluginNodes.Models;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -69,25 +70,23 @@ public void StopSimulation()

private void AddNodes(FolderState folder)
{
_node = _plcNodeManager.CreateVariableNode<double>(
_plcNodeManager.CreateBaseVariable(
folder,
path: "NegativeTrendData",
name: "NegativeTrendData",
new NodeId((uint)BuiltInType.Double),
ValueRanks.Scalar,
AccessLevels.CurrentRead,
"Value with a slow negative trend",
NamespaceType.OpcPlcApplications));
BaseDataVariableState variable = _plcNodeManager.CreateBaseVariable(
folder,
path: "NegativeTrendData",
name: "NegativeTrendData",
new NodeId((uint)BuiltInType.Double),
ValueRanks.Scalar,
AccessLevels.CurrentRead,
"Value with a slow negative trend",
NamespaceType.OpcPlcApplications);

_node = _plcNodeManager.CreateVariableNode<double>(variable);

// Add to node list for creation of pn.json.
Nodes = new List<NodeWithIntervals>
{
new NodeWithIntervals
{
NodeId = "NegativeTrendData",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
};
{
PluginNodesHelpers.GetNodeWithIntervals(variable.NodeId, _plcNodeManager),
};
}

private void AddMethods(FolderState methodsFolder)
Expand Down
35 changes: 17 additions & 18 deletions src/PluginNodes/OpaquePluginNode.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace OpcPlc.PluginNodes;

using Opc.Ua;
using OpcPlc.Helpers;
using OpcPlc.PluginNodes.Models;
using System.Collections.Generic;

Expand Down Expand Up @@ -57,25 +58,23 @@ public void StopSimulation()

private void AddNodes(FolderState folder)
{
_node = _plcNodeManager.CreateVariableNode<uint>(
_plcNodeManager.CreateBaseVariable(
folder,
path: new byte[] { (byte)'a', (byte)'b', (byte)'c' },
name: "Opaque_abc",
new NodeId((uint)BuiltInType.UInt32),
ValueRanks.Scalar,
AccessLevels.CurrentReadOrWrite,
"Constantly increasing value",
NamespaceType.OpcPlcApplications,
defaultValue: (uint)0));
BaseDataVariableState variable = _plcNodeManager.CreateBaseVariable(
folder,
path: new byte[] { (byte)'a', (byte)'b', (byte)'c' },
name: "Opaque_abc",
new NodeId((uint)BuiltInType.UInt32),
ValueRanks.Scalar,
AccessLevels.CurrentReadOrWrite,
"Constantly increasing value",
NamespaceType.OpcPlcApplications,
defaultValue: (uint)0);

_node = _plcNodeManager.CreateVariableNode<uint>(variable);

// Add to node list for creation of pn.json.
Nodes = new List<NodeWithIntervals>
{
new NodeWithIntervals
{
NodeId = "Opaque_abc",
Namespace = OpcPlc.Namespaces.OpcPlcApplications,
},
};
{
PluginNodesHelpers.GetNodeWithIntervals(variable.NodeId, _plcNodeManager),
};
}
}
Loading

0 comments on commit f4ae203

Please sign in to comment.