@aryacode/dsh-engineering 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.md +6 -6
- package/cordis.patch.yml +1 -1
- package/entries/netlogic.js +266 -0
- package/entries/optix.js +13 -0
- package/package.json +3 -2
- package/vendor/optix/SKILL.md +68 -0
- package/vendor/optix/netlogic/SOURCE.json +12 -0
- package/vendor/optix/netlogic/index.json +1987 -0
- package/vendor/optix/netlogic/pages/accessing-project-nodes.md +113 -0
- package/vendor/optix/netlogic/pages/advanced-svg.md +124 -0
- package/vendor/optix/netlogic/pages/alarming.md +489 -0
- package/vendor/optix/netlogic/pages/async-tasks.md +236 -0
- package/vendor/optix/netlogic/pages/audit-signature.md +91 -0
- package/vendor/optix/netlogic/pages/colors.md +122 -0
- package/vendor/optix/netlogic/pages/companion-specs.md +77 -0
- package/vendor/optix/netlogic/pages/creating-objects.md +370 -0
- package/vendor/optix/netlogic/pages/database-interaction.md +437 -0
- package/vendor/optix/netlogic/pages/datagrids.md +123 -0
- package/vendor/optix/netlogic/pages/debugging-tips.md +605 -0
- package/vendor/optix/netlogic/pages/designtime-tags-import.md +531 -0
- package/vendor/optix/netlogic/pages/dialog-boxes.md +150 -0
- package/vendor/optix/netlogic/pages/dispatch-events.md +200 -0
- package/vendor/optix/netlogic/pages/dynamic-links.md +825 -0
- package/vendor/optix/netlogic/pages/element-access.md +1208 -0
- package/vendor/optix/netlogic/pages/engineering-units.md +298 -0
- package/vendor/optix/netlogic/pages/events.md +340 -0
- package/vendor/optix/netlogic/pages/execute-command.md +202 -0
- package/vendor/optix/netlogic/pages/fto-studio-cli.md +99 -0
- package/vendor/optix/netlogic/pages/good-practices.md +50 -0
- package/vendor/optix/netlogic/pages/information-model.md +89 -0
- package/vendor/optix/netlogic/pages/log-output.md +22 -0
- package/vendor/optix/netlogic/pages/managing-aliases.md +22 -0
- package/vendor/optix/netlogic/pages/manipulate-nodes.md +72 -0
- package/vendor/optix/netlogic/pages/mqtt.md +240 -0
- package/vendor/optix/netlogic/pages/netlogic-lifecycle.md +270 -0
- package/vendor/optix/netlogic/pages/netlogic-overview.md +155 -0
- package/vendor/optix/netlogic/pages/opcua.md +325 -0
- package/vendor/optix/netlogic/pages/plc-tags.md +219 -0
- package/vendor/optix/netlogic/pages/queries.md +1297 -0
- package/vendor/optix/netlogic/pages/random-generation.md +90 -0
- package/vendor/optix/netlogic/pages/recipes.md +375 -0
- package/vendor/optix/netlogic/pages/recipex.md +2383 -0
- package/vendor/optix/netlogic/pages/regex.md +15 -0
- package/vendor/optix/netlogic/pages/register-observers.md +346 -0
- package/vendor/optix/netlogic/pages/reports.md +141 -0
- package/vendor/optix/netlogic/pages/resource-uri.md +308 -0
- package/vendor/optix/netlogic/pages/runtime-tags-import.md +280 -0
- package/vendor/optix/netlogic/pages/serial-port.md +357 -0
- package/vendor/optix/netlogic/pages/sessions.md +58 -0
- package/vendor/optix/netlogic/pages/system-node.md +153 -0
- package/vendor/optix/netlogic/pages/template-library.md +127 -0
- package/vendor/optix/netlogic/pages/threading.md +236 -0
- package/vendor/optix/netlogic/pages/translations.md +417 -0
- package/vendor/optix/netlogic/pages/trends.md +128 -0
- package/vendor/optix/netlogic/pages/ui-animations.md +115 -0
- package/vendor/optix/netlogic/pages/users-groups.md +416 -0
- package/vendor/optix/netlogic/pages/variables-formatting.md +16 -0
- package/vendor/optix/netlogic/pages/variables-interaction.md +557 -0
- package/vendor/optix/netlogic/pages/variables-structure.md +155 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Accessing project nodes
|
|
2
|
+
|
|
3
|
+
Before reading this page, please make sure to have the concept of [InformationModel and Session](./information-model.md).
|
|
4
|
+
|
|
5
|
+
## Navigating to a node
|
|
6
|
+
|
|
7
|
+
### The `Node.Get` syntax
|
|
8
|
+
|
|
9
|
+
The `Get` method is used to fetch nodes from the current project, it can retrieve both session and global objects (nodes), this method also accepts a type that will be passed to the variable type
|
|
10
|
+
- Example:
|
|
11
|
+
- `var myButton = … .Get<Button>("path/to/button");` -> Will create a _myButton_ variable of Type `FTOptix.UI.Button` pointing to the desired element
|
|
12
|
+
- After the object has been casted to the proper path, you can access its properties using IntelliSense
|
|
13
|
+
- Example:
|
|
14
|
+
- `myButton.Text = Hello;`
|
|
15
|
+
|
|
16
|
+
### Accessing global objects
|
|
17
|
+
|
|
18
|
+
In order to manipulate any project element, you first need to access it, this can be either done by getting its NodeId or its node object
|
|
19
|
+
|
|
20
|
+
- Examples:
|
|
21
|
+
- `var myNodeId = Project.Current.Get( [path/to/node] ).NodeId;`
|
|
22
|
+
- `var myObject = Project.Current.Get( [path/to/node] );`
|
|
23
|
+
|
|
24
|
+
- Where `path/to/node` can be obtained by right clicking any element of the IDE and then clicking `Copy path to node`, here you need to remember to remove the project name from the pasted element
|
|
25
|
+
- Example:
|
|
26
|
+
- `NewHMIProject25/Model/MyCustomMotor` --> `Model/MyCustomMotor`
|
|
27
|
+
|
|
28
|
+
### Accessing session-based objects
|
|
29
|
+
|
|
30
|
+
Now that we know how session works, it's easy to understand the benefits of placing a NetLogic in a session-based object (such as the page you want to access or manipulate) and then use the relative addressing to retrieve the right element
|
|
31
|
+
- Example:
|
|
32
|
+
- `var ButtonText = Owner.Get("MotorButton/Text");`
|
|
33
|
+
|
|
34
|
+
### The `Node.Find` syntax
|
|
35
|
+
|
|
36
|
+
You can also search for a specific object by knowing its `BrowseName` by using the `Find` method, this can be useful but it is not recommended as it is very slow to perform (it will recursively browse the whole project until it gets to the first element with such node)
|
|
37
|
+
- Example:
|
|
38
|
+
- `var myObj = Project.Current.Find("ObjectName");`
|
|
39
|
+
|
|
40
|
+
## Casting vs Type passing
|
|
41
|
+
|
|
42
|
+
### Passing the object type
|
|
43
|
+
|
|
44
|
+
Type parameter can be used with "generic methods" that allows using different types. A generic method can be called either without an argument (anything that applies to any node such as `BrowseName` or `NodeId`) or by specifying the type of argument within angle brackets
|
|
45
|
+
- Example:
|
|
46
|
+
- `var myfolder = Project.Current.Get<Folder>("Model\MyFolder");`
|
|
47
|
+
|
|
48
|
+
Using this type passing option, the returned node is `null` if:
|
|
49
|
+
- Node does not exist
|
|
50
|
+
- The node does not match the specified type (e.g: `MyFolder` is an `Object` and not a `Folder`)
|
|
51
|
+
|
|
52
|
+
### Casting from IUANode
|
|
53
|
+
|
|
54
|
+
A cast is an explicit conversion, to perform a cast, specify the type that you are casting to in parentheses in front of the value or variable to be converted.
|
|
55
|
+
- Example:
|
|
56
|
+
- `var myfolder = (Folder)Project.Current.Get("Model\MyFolder");`
|
|
57
|
+
|
|
58
|
+
Using this casting option, the node is returned as null only if completely missing, if the object type cannot be casted, an exception is thrown.
|
|
59
|
+
|
|
60
|
+
### Summary
|
|
61
|
+
|
|
62
|
+
Result is very similar, as best practice we suggest to use the type passing approach unless casting is a specific requirement to achieve the result
|
|
63
|
+
|
|
64
|
+
## Accessing an object by NodeId (pointer)
|
|
65
|
+
|
|
66
|
+
```csharp
|
|
67
|
+
/// <summary>
|
|
68
|
+
/// Access an object by passing a NodeId pointer to a NetLogic variable. This keeps references valid even if the object is moved in the project tree.
|
|
69
|
+
/// </summary>
|
|
70
|
+
// Example: assume a NodeId variable named "ObjectPointer" exists and contains the NodeId of the target object
|
|
71
|
+
var myObjectNodeId = LogicObject.GetVariable("ObjectPointer").Value;
|
|
72
|
+
var myRectangle = InformationModel.Get<Rectangle>(myObjectNodeId);
|
|
73
|
+
// Now use myRectangle as the referenced object
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Use ChildrenRemoteRead to inspect an aliased object structure
|
|
77
|
+
|
|
78
|
+
```csharp
|
|
79
|
+
/// <summary>
|
|
80
|
+
/// When an object is aliased (for example via an Alias pointer), `ChildrenRemoteRead` lets you fetch a lightweight view
|
|
81
|
+
/// of the aliased object's children without creating full session objects. This is handy to read a structure's values.
|
|
82
|
+
/// </summary>
|
|
83
|
+
// Example: assume `LightPointer` is an alias variable pointing to a UI object.
|
|
84
|
+
var refLight = LogicObject.GetAlias("LightPointer");
|
|
85
|
+
if (refLight != null)
|
|
86
|
+
{
|
|
87
|
+
var structure = refLight.ChildrenRemoteRead();
|
|
88
|
+
Log.Info("IntermittentMode value: " + structure.SingleOrDefault(item => item.RelativePath == "IntermittentMode").Value);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Count nodes under a specific page/object
|
|
93
|
+
|
|
94
|
+
```csharp
|
|
95
|
+
/// <summary>
|
|
96
|
+
/// Count the number of nodes under a given NodeId and log the result.
|
|
97
|
+
/// Input: NodeId of the starting node.
|
|
98
|
+
/// Output: Logs the count to Info.
|
|
99
|
+
/// </summary>
|
|
100
|
+
[ExportMethod]
|
|
101
|
+
public static int GetNodesNumber(NodeId nodeId) => InformationModel.Get(nodeId).FindNodesByType<IUANode>().Count();
|
|
102
|
+
|
|
103
|
+
[ExportMethod]
|
|
104
|
+
public void CounNodes()
|
|
105
|
+
{
|
|
106
|
+
// Example: log node counts for two screens
|
|
107
|
+
var unit02 = Project.Current.Get("UI/Screens/Pages/Un02/Em02_Pref/Unit02Em02");
|
|
108
|
+
var unit00 = Project.Current.Get("UI/Screens/Pages/Un00/Unit00");
|
|
109
|
+
|
|
110
|
+
Log.Info("Unit02Em02: " + GetNodesNumber(unit02.NodeId).ToString());
|
|
111
|
+
Log.Info("Unit00: " + GetNodesNumber(unit00.NodeId).ToString());
|
|
112
|
+
}
|
|
113
|
+
```
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Advanced SVG image
|
|
2
|
+
|
|
3
|
+
## SetImageContent
|
|
4
|
+
|
|
5
|
+
The AdvancedSVGImage container, supports direct manipulation of the image buffer, allowing for fast and direct access to the content, this allows runtime editing that can efficiently manipulate the path or properties of an SVG image without impacting the InformationModel
|
|
6
|
+
|
|
7
|
+
> [!NOTE]
|
|
8
|
+
> This feature was introduced in FT Optix 1.4.x
|
|
9
|
+
|
|
10
|
+
> [!NOTE]
|
|
11
|
+
> The `SetImageContent` writes in the image buffer, so it does not trigger a change in the InformationModel, and it will not work at DesignTime, it is meant to be used at Runtime for animation or dynamic image manipulation.
|
|
12
|
+
|
|
13
|
+
> [!NOTE]
|
|
14
|
+
> As the `SetImageContent` method writes directly in the image buffer, if the page is reloaded or if the image source is changed, the changes will be lost, and the original SVG will be loaded again.
|
|
15
|
+
|
|
16
|
+
### Sample image
|
|
17
|
+
|
|
18
|
+
This is the sample image (containing a "star" shape) that we used in the examples below to be animated
|
|
19
|
+
|
|
20
|
+
```svg
|
|
21
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
22
|
+
<svg version="1.1" id="Overall" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" viewBox="0 0 300 300">
|
|
23
|
+
<g id="MyPaths" opacity="1.0">
|
|
24
|
+
<path style="fill:#3C4660;" d="M 0 67.2262 L 72.1921 67.2262 L 94.5 0 L 116.8079 67.2262 L 189 67.2262 L 130.5954 108.7738 L 152.9045 176 L 94.5 134.4513 L 36.0954 176 L 58.4045 108.7738 L 0 67.2262 Z" transform="rotate(0, 150, 219)"/>
|
|
25
|
+
</g>
|
|
26
|
+
<g id="Box1">
|
|
27
|
+
<polygon style="fill:#CB8252;" points="25,270 75,270 75,220 25,220" transform="rotate(0, 20, 20)"/>
|
|
28
|
+
</g>
|
|
29
|
+
</svg>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Making the image disappear
|
|
33
|
+
|
|
34
|
+
```csharp
|
|
35
|
+
[ExportMethod]
|
|
36
|
+
public void replaceSVG()
|
|
37
|
+
{
|
|
38
|
+
// LogicObject.Owner is the button, so LogicObject.Owner is the MainWindow
|
|
39
|
+
AdvancedSVGImage svgImage = LogicObject.Owner.Get<AdvancedSVGImage>("AdvancedSVGImage1");
|
|
40
|
+
|
|
41
|
+
string myXML = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\r\n<svg version=\"1.1\" id=\"Overall\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xml:space=\"preserve\" viewBox=\"0 0 300 300\">\r\n <g id=\"Box1\">\r\n <polygon style=\"fill:#CB8252;\" points=\"25,270 75,270 75,220 25,220\" transform=\"rotate(0, 20, 20)\"/>\r\n </g>\r\n</svg>\r\n";
|
|
42
|
+
|
|
43
|
+
//Update the SVG
|
|
44
|
+
svgImage.SetImageContent(myXML);
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Rotate the image
|
|
49
|
+
|
|
50
|
+
```csharp
|
|
51
|
+
#region Using directives
|
|
52
|
+
using FTOptix.NetLogic;
|
|
53
|
+
using FTOptix.UI;
|
|
54
|
+
using System.Xml.Linq;
|
|
55
|
+
using System.Linq;
|
|
56
|
+
using UAManagedCore;
|
|
57
|
+
using System.Threading;
|
|
58
|
+
#endregion
|
|
59
|
+
|
|
60
|
+
public class RuntimeNetLogic1 : BaseNetLogic
|
|
61
|
+
{
|
|
62
|
+
public override void Start()
|
|
63
|
+
{
|
|
64
|
+
// LogicObject.Owner is the button, so LogicObject.Owner is the MainWindow
|
|
65
|
+
svgImage = LogicObject.Owner.Get<AdvancedSVGImage>("AdvancedSVGImage1");
|
|
66
|
+
// Retrieve the Path to the SVG
|
|
67
|
+
var imageAbsolutePath = svgImage.Path.Uri;
|
|
68
|
+
// Load the SVG into an XDocument
|
|
69
|
+
xDocument = XDocument.Load(imageAbsolutePath);
|
|
70
|
+
// Find the first path element
|
|
71
|
+
var pathNode = xDocument.Descendants().Where(x => x.Name.LocalName == "path").FirstOrDefault();
|
|
72
|
+
// Find the first polygon element
|
|
73
|
+
var polyNode = xDocument.Descendants().Where(x => x.Name.LocalName == "polygon").FirstOrDefault();
|
|
74
|
+
// Get the polygon transform attribute
|
|
75
|
+
polyTransformAttribute = polyNode.Attribute("transform");
|
|
76
|
+
// Get the polygon transform attribute
|
|
77
|
+
pathTransformAttribute = pathNode.Attribute("transform");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public override void Stop()
|
|
81
|
+
{
|
|
82
|
+
keepGoing = false;
|
|
83
|
+
if (myLRT != null)
|
|
84
|
+
myLRT.Dispose();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private void doRotate()
|
|
88
|
+
{
|
|
89
|
+
int degrees = 3;
|
|
90
|
+
while (keepGoing)
|
|
91
|
+
{
|
|
92
|
+
Thread.Sleep(50);
|
|
93
|
+
degrees += 3;
|
|
94
|
+
if (degrees > 360)
|
|
95
|
+
degrees = 0;
|
|
96
|
+
string newTransformPoly = new string("rotate(" + degrees + ", 50, 250)");
|
|
97
|
+
polyTransformAttribute.SetValue(newTransformPoly);
|
|
98
|
+
string newTransformPath = new string("rotate(" + degrees + ", 96, 97)");
|
|
99
|
+
pathTransformAttribute.SetValue(newTransformPath);
|
|
100
|
+
//Update the SVG
|
|
101
|
+
svgImage.SetImageContent(xDocument.ToString());
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
[ExportMethod]
|
|
106
|
+
public void rotateSVG()
|
|
107
|
+
{
|
|
108
|
+
keepGoing = false;
|
|
109
|
+
if (myLRT != null)
|
|
110
|
+
myLRT.Dispose();
|
|
111
|
+
keepGoing = true;
|
|
112
|
+
myLRT = new LongRunningTask(doRotate, LogicObject);
|
|
113
|
+
myLRT.Start();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private XDocument xDocument;
|
|
117
|
+
private AdvancedSVGImage svgImage;
|
|
118
|
+
private XAttribute polyTransformAttribute;
|
|
119
|
+
private XAttribute pathTransformAttribute;
|
|
120
|
+
private LongRunningTask myLRT;
|
|
121
|
+
private bool keepGoing = true;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|