nodalis-compiler 1.0.31 → 1.0.32
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 +3 -0
- package/package.json +4 -1
- package/src/compilers/JSCompiler.js +15 -0
- package/src/compilers/support/generic/modbus.cpp +57 -18
- package/src/compilers/support/jint/nodalis/NodalisEngine/NodalisEngine.csproj +2 -2
- package/src/compilers/support/jint/nodalis/NodalisEngine/OPCClient.cs +63 -10
- package/src/compilers/support/jint/nodalis/NodalisEngine/OPCServer.cs +69 -9
- package/src/compilers/support/jint/nodalis/NodalisEngine/README.md +5 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Debug/net8.0/NodalisEngine.deps.json +263 -162
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Debug/net8.0/NodalisEngine.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Debug/net8.0/NodalisEngine.pdb +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Debug/net8.0/NodalisEngine.xml +2 -1
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Release/NodalisEngine.1.0.10.nupkg +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Release/NodalisEngine.1.0.11.nupkg +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Release/NodalisEngine.1.0.12.nupkg +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Release/net8.0/NodalisEngine.deps.json +263 -162
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Release/net8.0/NodalisEngine.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Release/net8.0/NodalisEngine.pdb +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/bin/Release/net8.0/NodalisEngine.xml +2 -1
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/NodalisEngine.AssemblyInfo.cs +3 -3
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/NodalisEngine.AssemblyInfoInputs.cache +1 -1
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/NodalisEngine.assets.cache +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/NodalisEngine.csproj.AssemblyReference.cache +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/NodalisEngine.csproj.CoreCompileInputs.cache +1 -1
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/NodalisEngine.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/NodalisEngine.pdb +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/NodalisEngine.sourcelink.json +1 -1
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/NodalisEngine.xml +2 -1
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/ref/NodalisEngine.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Debug/net8.0/refint/NodalisEngine.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/NodalisEngine.csproj.nuget.dgspec.json +2 -2
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/NodalisEngine.csproj.nuget.g.targets +3 -2
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/NodalisEngine.1.0.10.nuspec +2 -2
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/NodalisEngine.1.0.11.nuspec +31 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/NodalisEngine.1.0.12.nuspec +31 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/NodalisEngine.AssemblyInfo.cs +3 -3
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/NodalisEngine.AssemblyInfoInputs.cache +1 -1
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/NodalisEngine.assets.cache +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/NodalisEngine.csproj.AssemblyReference.cache +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/NodalisEngine.csproj.CoreCompileInputs.cache +1 -1
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/NodalisEngine.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/NodalisEngine.pdb +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/NodalisEngine.sourcelink.json +1 -1
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/NodalisEngine.xml +2 -1
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/ref/NodalisEngine.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/Release/net8.0/refint/NodalisEngine.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/project.assets.json +495 -224
- package/src/compilers/support/jint/nodalis/NodalisEngine/obj/project.nuget.cache +24 -19
- package/src/compilers/support/jint/nodalis/NodalisPLC/Program.cs +14 -5
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/BouncyCastle.Cryptography.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Esprima.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Jint.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Microsoft.Extensions.DependencyInjection.Abstractions.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Microsoft.Extensions.Logging.Abstractions.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Newtonsoft.Json.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/NodalisEngine.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/NodalisEngine.pdb +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/NodalisEngine.xml +0 -693
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/NodalisPLC +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/NodalisPLC.deps.json +0 -358
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/NodalisPLC.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/NodalisPLC.pdb +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/NodalisPLC.runtimeconfig.json +0 -12
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Opc.Ua.Client.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Opc.Ua.Configuration.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Opc.Ua.Core.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Opc.Ua.Gds.Client.Common.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Opc.Ua.Gds.Server.Common.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Opc.Ua.Security.Certificates.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/Opc.Ua.Server.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/System.IO.Pipelines.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/System.Text.Encodings.Web.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/System.Text.Json.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/bin/Debug/net8.0/runtimes/browser/lib/net8.0/System.Text.Encodings.Web.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs +0 -4
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.AssemblyInfo.cs +0 -22
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.AssemblyInfoInputs.cache +0 -1
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.GeneratedMSBuildEditorConfig.editorconfig +0 -15
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.GlobalUsings.g.cs +0 -8
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.assets.cache +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.csproj.AssemblyReference.cache +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.csproj.CoreCompileInputs.cache +0 -1
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.csproj.FileListAbsolute.txt +0 -37
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.csproj.Up2Date +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.genruntimeconfig.cache +0 -1
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.pdb +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/NodalisPLC.sourcelink.json +0 -1
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/apphost +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/ref/NodalisPLC.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/Debug/net8.0/refint/NodalisPLC.dll +0 -0
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/NodalisPLC.csproj.nuget.dgspec.json +0 -282
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/NodalisPLC.csproj.nuget.g.props +0 -15
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/NodalisPLC.csproj.nuget.g.targets +0 -7
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/project.assets.json +0 -3181
- package/src/compilers/support/jint/nodalis/NodalisPLC/obj/project.nuget.cache +0 -51
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodalis-compiler",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.32",
|
|
4
4
|
"description": "Compiles IEC-61131-3/10 languages into code that can be used as a PLC on multiple platforms.",
|
|
5
5
|
"icon": "nodalis.png",
|
|
6
6
|
"main": "src/nodalis.js",
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"src/",
|
|
19
|
+
"!src/compilers/support/jint/nodalis/NodalisPLC/bin/",
|
|
20
|
+
"!src/compilers/support/jint/nodalis/NodalisPLC/obj/",
|
|
21
|
+
"!src/compilers/support/jint/nodalis/publish/",
|
|
19
22
|
"README.md",
|
|
20
23
|
"LICENSE",
|
|
21
24
|
"package.json",
|
|
@@ -114,6 +114,7 @@ export class JSCompiler extends Compiler {
|
|
|
114
114
|
let tasks = [];
|
|
115
115
|
let programs = [];
|
|
116
116
|
let globals = [];
|
|
117
|
+
let csharpGlobals = [];
|
|
117
118
|
let taskCode = "";
|
|
118
119
|
let mapCode = "";
|
|
119
120
|
let plcname = "NodalisPLC";
|
|
@@ -143,6 +144,7 @@ export class JSCompiler extends Compiler {
|
|
|
143
144
|
else if(line.indexOf("//Global=") > -1){
|
|
144
145
|
let global = JSON.parse(line.substring(line.indexOf("=") + 1).trim());
|
|
145
146
|
globals.push(`opcServer.mapVariable("${global.Name}", "${global.Address}");`)
|
|
147
|
+
csharpGlobals.push(`opcServer.MapVariable(${toCSharpStringLiteral(global.Name)}, ${toCSharpStringLiteral(global.Address)});`)
|
|
146
148
|
|
|
147
149
|
}
|
|
148
150
|
else if(line.trim().startsWith("PROGRAM")){
|
|
@@ -273,6 +275,7 @@ export function run(){
|
|
|
273
275
|
|
|
274
276
|
// Keep the Jint project sources in the main output directory.
|
|
275
277
|
fs.cpSync(supportDir, projectOutputDir, { recursive: true, force: true });
|
|
278
|
+
patchJintProgramOpcMappings(projectOutputDir, csharpGlobals);
|
|
276
279
|
|
|
277
280
|
// Build from the main output directory, then move publish artifacts under bin.
|
|
278
281
|
const buildPath = path.resolve(path.join(projectOutputDir, buildScript));
|
|
@@ -347,3 +350,15 @@ function installDependencies(outputDir) {
|
|
|
347
350
|
shell: true
|
|
348
351
|
});
|
|
349
352
|
}
|
|
353
|
+
|
|
354
|
+
function patchJintProgramOpcMappings(projectOutputDir, csharpGlobals) {
|
|
355
|
+
const programPath = path.join(projectOutputDir, "NodalisPLC", "Program.cs");
|
|
356
|
+
let programSource = fs.readFileSync(programPath, "utf-8");
|
|
357
|
+
const mappingCode = csharpGlobals.map((line) => ` ${line}`).join("\n");
|
|
358
|
+
programSource = programSource.replace(" // {opcServerMappings}", mappingCode);
|
|
359
|
+
fs.writeFileSync(programPath, programSource, "utf-8");
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
function toCSharpStringLiteral(value) {
|
|
363
|
+
return `"${String(value).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`;
|
|
364
|
+
}
|
|
@@ -197,47 +197,86 @@ ModbusRequest ModbusClient::createWriteSingleRegister(uint16_t address, uint16_t
|
|
|
197
197
|
return { deviceAddress, WRITE_SINGLE_REGISTER, address, 1, data };
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
bool ModbusClient::sendRequest(const ModbusRequest&
|
|
200
|
+
bool ModbusClient::sendRequest(const ModbusRequest &req, ModbusResponse &resp)
|
|
201
|
+
{
|
|
201
202
|
std::vector<uint8_t> pdu;
|
|
202
203
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
204
|
+
if (req.function == WRITE_SINGLE_COIL)
|
|
205
|
+
{
|
|
206
|
+
pdu = {
|
|
207
|
+
req.function,
|
|
208
|
+
static_cast<uint8_t>(req.startAddress >> 8),
|
|
209
|
+
static_cast<uint8_t>(req.startAddress & 0xFF)};
|
|
210
|
+
|
|
211
|
+
if (req.data.size() != 2)
|
|
212
|
+
{
|
|
213
|
+
std::cerr << "Invalid data size for Write Single Coil.\n";
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
pdu.push_back(req.data[0]);
|
|
218
|
+
pdu.push_back(req.data[1]);
|
|
219
|
+
}
|
|
220
|
+
else if (req.function == WRITE_SINGLE_REGISTER)
|
|
221
|
+
{
|
|
206
222
|
pdu = {
|
|
207
223
|
req.function,
|
|
208
224
|
static_cast<uint8_t>(req.startAddress >> 8),
|
|
209
|
-
static_cast<uint8_t>(req.startAddress & 0xFF)
|
|
210
|
-
|
|
211
|
-
if (req.data.size()
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
} else {
|
|
215
|
-
std::cerr << "Invalid data size for Write Single Coil (expected 2 bytes).\n";
|
|
225
|
+
static_cast<uint8_t>(req.startAddress & 0xFF)};
|
|
226
|
+
|
|
227
|
+
if (req.data.size() != 2)
|
|
228
|
+
{
|
|
229
|
+
std::cerr << "Invalid data size for Write Single Register.\n";
|
|
216
230
|
return false;
|
|
217
231
|
}
|
|
218
|
-
|
|
219
|
-
//
|
|
232
|
+
|
|
233
|
+
pdu.push_back(req.data[0]); // value high byte
|
|
234
|
+
pdu.push_back(req.data[1]); // value low byte
|
|
235
|
+
}
|
|
236
|
+
else if (req.function == READ_HOLDING_REGISTERS ||
|
|
237
|
+
req.function == READ_INPUT_REGISTERS ||
|
|
238
|
+
req.function == READ_COILS ||
|
|
239
|
+
req.function == READ_DISCRETE_INPUTS)
|
|
240
|
+
{
|
|
220
241
|
pdu = {
|
|
221
242
|
req.function,
|
|
222
243
|
static_cast<uint8_t>(req.startAddress >> 8),
|
|
223
244
|
static_cast<uint8_t>(req.startAddress & 0xFF),
|
|
224
245
|
static_cast<uint8_t>(req.quantity >> 8),
|
|
225
|
-
static_cast<uint8_t>(req.quantity & 0xFF)
|
|
226
|
-
|
|
246
|
+
static_cast<uint8_t>(req.quantity & 0xFF)};
|
|
247
|
+
}
|
|
248
|
+
else if (req.function == WRITE_MULTIPLE_REGISTERS)
|
|
249
|
+
{
|
|
250
|
+
pdu = {
|
|
251
|
+
req.function,
|
|
252
|
+
static_cast<uint8_t>(req.startAddress >> 8),
|
|
253
|
+
static_cast<uint8_t>(req.startAddress & 0xFF),
|
|
254
|
+
static_cast<uint8_t>(req.quantity >> 8),
|
|
255
|
+
static_cast<uint8_t>(req.quantity & 0xFF),
|
|
256
|
+
static_cast<uint8_t>(req.data.size())};
|
|
257
|
+
|
|
227
258
|
pdu.insert(pdu.end(), req.data.begin(), req.data.end());
|
|
228
259
|
}
|
|
260
|
+
else
|
|
261
|
+
{
|
|
262
|
+
std::cerr << "Unsupported Modbus function: " << static_cast<int>(req.function) << "\n";
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
229
265
|
|
|
230
266
|
std::vector<uint8_t> response;
|
|
231
|
-
if (!sendRaw(pdu, response))
|
|
267
|
+
if (!sendRaw(pdu, response))
|
|
268
|
+
return false;
|
|
232
269
|
|
|
233
|
-
if (response.size() < 2)
|
|
270
|
+
if (response.size() < 2)
|
|
271
|
+
return false;
|
|
234
272
|
|
|
235
273
|
resp.address = req.address;
|
|
236
274
|
resp.function = response[0];
|
|
237
275
|
resp.data.assign(response.begin() + 1, response.end());
|
|
238
276
|
resp.exceptionCode = (resp.function & 0x80) ? resp.data[0] : 0;
|
|
239
277
|
|
|
240
|
-
if (resp.exceptionCode > 0)
|
|
278
|
+
if (resp.exceptionCode > 0)
|
|
279
|
+
{
|
|
241
280
|
std::cerr << "MODBUS exception code: " << static_cast<int>(resp.exceptionCode) << "\n";
|
|
242
281
|
return false;
|
|
243
282
|
}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<PackageReference Include="BACnet" Version="3.0.2" />
|
|
13
13
|
<PackageReference Include="Jint" Version="4.4.2" />
|
|
14
14
|
<PackageReference Include="System.Text.Json" Version="*" />
|
|
15
|
-
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua" Version="1.5.
|
|
15
|
+
<PackageReference Include="OPCFoundation.NetStandard.Opc.Ua" Version="1.5.378.134" />
|
|
16
16
|
</ItemGroup>
|
|
17
17
|
<ItemGroup>
|
|
18
18
|
<None Include="README.md" Pack="true" PackagePath="\" />
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<PropertyGroup>
|
|
25
25
|
<TargetFrameworks>net8.0</TargetFrameworks>
|
|
26
26
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <!-- optional -->
|
|
27
|
-
<Version>1.0.
|
|
27
|
+
<Version>1.0.12</Version>
|
|
28
28
|
<Authors>Nathan Skipper</Authors>
|
|
29
29
|
<Company>Montgomery Technology, Inc.</Company>
|
|
30
30
|
<PackageId>NodalisEngine</PackageId>
|
|
@@ -21,6 +21,7 @@ using Opc.Ua.Client;
|
|
|
21
21
|
using Opc.Ua.Configuration;
|
|
22
22
|
using System;
|
|
23
23
|
using System.Collections.Generic;
|
|
24
|
+
using System.IO;
|
|
24
25
|
using System.Threading.Tasks;
|
|
25
26
|
|
|
26
27
|
namespace Nodalis
|
|
@@ -30,7 +31,7 @@ namespace Nodalis
|
|
|
30
31
|
/// </summary>
|
|
31
32
|
public class OPCClient : IOClient
|
|
32
33
|
{
|
|
33
|
-
private
|
|
34
|
+
private ISession? _session;
|
|
34
35
|
private ApplicationConfiguration? _config;
|
|
35
36
|
/// <summary>
|
|
36
37
|
/// Instantiates a new OPCClient.
|
|
@@ -52,23 +53,35 @@ namespace Nodalis
|
|
|
52
53
|
{
|
|
53
54
|
ApplicationName = "NodalisOPCUAClient",
|
|
54
55
|
ApplicationType = ApplicationType.Client,
|
|
55
|
-
SecurityConfiguration =
|
|
56
|
-
{
|
|
57
|
-
ApplicationCertificate = new CertificateIdentifier(),
|
|
58
|
-
AutoAcceptUntrustedCertificates = true,
|
|
59
|
-
},
|
|
56
|
+
SecurityConfiguration = CreateSecurityConfiguration(),
|
|
60
57
|
TransportConfigurations = new TransportConfigurationCollection(),
|
|
61
58
|
TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
|
|
62
59
|
ClientConfiguration = new ClientConfiguration { DefaultSessionTimeout = 60000 }
|
|
63
60
|
};
|
|
64
61
|
await _config.Validate(ApplicationType.Client);
|
|
62
|
+
await _config.CertificateValidator.UpdateAsync(_config, default);
|
|
65
63
|
|
|
66
64
|
var app = new ApplicationInstance { ApplicationName = "NodalisOPCUAClient", ApplicationType = ApplicationType.Client, ApplicationConfiguration = _config };
|
|
67
|
-
|
|
68
|
-
var endpointConfig = EndpointConfiguration.Create(_config);
|
|
69
|
-
var endpointDesc = new ConfiguredEndpoint(null, endpoint, endpointConfig);
|
|
65
|
+
await app.CheckApplicationInstanceCertificatesAsync(false, 0);
|
|
70
66
|
|
|
71
|
-
|
|
67
|
+
var endpoint = CoreClientUtils.SelectEndpoint(_config, endpointUrl, false, 15000);
|
|
68
|
+
var endpointConfig = EndpointConfiguration.Create(_config);
|
|
69
|
+
var configuredEndpoint = new ConfiguredEndpoint(null, endpoint, endpointConfig);
|
|
70
|
+
|
|
71
|
+
var sessionFactory = new DefaultSessionFactory();
|
|
72
|
+
|
|
73
|
+
_session = await sessionFactory.CreateAsync(
|
|
74
|
+
_config,
|
|
75
|
+
(ITransportWaitingConnection?)null,
|
|
76
|
+
configuredEndpoint,
|
|
77
|
+
true,
|
|
78
|
+
false,
|
|
79
|
+
_config.ApplicationName,
|
|
80
|
+
60000,
|
|
81
|
+
new UserIdentity(),
|
|
82
|
+
null,
|
|
83
|
+
default
|
|
84
|
+
);
|
|
72
85
|
connected = true;
|
|
73
86
|
Console.WriteLine("OPC UA connected.");
|
|
74
87
|
}
|
|
@@ -80,6 +93,46 @@ namespace Nodalis
|
|
|
80
93
|
});
|
|
81
94
|
}
|
|
82
95
|
|
|
96
|
+
private static SecurityConfiguration CreateSecurityConfiguration()
|
|
97
|
+
{
|
|
98
|
+
string pkiRoot = Path.Combine(AppContext.BaseDirectory, "pki");
|
|
99
|
+
string ownStore = Path.Combine(pkiRoot, "own");
|
|
100
|
+
string trustedPeerStore = Path.Combine(pkiRoot, "trusted");
|
|
101
|
+
string trustedIssuerStore = Path.Combine(pkiRoot, "issuer");
|
|
102
|
+
string rejectedStore = Path.Combine(pkiRoot, "rejected");
|
|
103
|
+
|
|
104
|
+
Directory.CreateDirectory(ownStore);
|
|
105
|
+
Directory.CreateDirectory(trustedPeerStore);
|
|
106
|
+
Directory.CreateDirectory(trustedIssuerStore);
|
|
107
|
+
Directory.CreateDirectory(rejectedStore);
|
|
108
|
+
|
|
109
|
+
return new SecurityConfiguration
|
|
110
|
+
{
|
|
111
|
+
ApplicationCertificate = new CertificateIdentifier
|
|
112
|
+
{
|
|
113
|
+
StoreType = CertificateStoreType.Directory,
|
|
114
|
+
StorePath = ownStore,
|
|
115
|
+
SubjectName = "CN=NodalisOPCUAClient"
|
|
116
|
+
},
|
|
117
|
+
TrustedPeerCertificates = new CertificateTrustList
|
|
118
|
+
{
|
|
119
|
+
StoreType = CertificateStoreType.Directory,
|
|
120
|
+
StorePath = trustedPeerStore
|
|
121
|
+
},
|
|
122
|
+
TrustedIssuerCertificates = new CertificateTrustList
|
|
123
|
+
{
|
|
124
|
+
StoreType = CertificateStoreType.Directory,
|
|
125
|
+
StorePath = trustedIssuerStore
|
|
126
|
+
},
|
|
127
|
+
RejectedCertificateStore = new CertificateTrustList
|
|
128
|
+
{
|
|
129
|
+
StoreType = CertificateStoreType.Directory,
|
|
130
|
+
StorePath = rejectedStore
|
|
131
|
+
},
|
|
132
|
+
AutoAcceptUntrustedCertificates = true
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
83
136
|
private NodeId GetNodeId(string remote) => new NodeId($"s={remote}", 1);
|
|
84
137
|
|
|
85
138
|
public override bool ReadBit(string address, out int result)
|
|
@@ -21,6 +21,7 @@ using Opc.Ua.Configuration;
|
|
|
21
21
|
using Opc.Ua.Server;
|
|
22
22
|
using System;
|
|
23
23
|
using System.Collections.Generic;
|
|
24
|
+
using System.IO;
|
|
24
25
|
using System.Threading.Tasks;
|
|
25
26
|
|
|
26
27
|
namespace Nodalis
|
|
@@ -57,8 +58,9 @@ namespace Nodalis
|
|
|
57
58
|
/// <summary>
|
|
58
59
|
/// Starts the server.
|
|
59
60
|
/// </summary>
|
|
61
|
+
/// <param name="hostname">The hostname or IP address for the server.</param>
|
|
60
62
|
/// <returns></returns>
|
|
61
|
-
public async Task StartAsync()
|
|
63
|
+
public async Task StartAsync(string hostname = "localhost")
|
|
62
64
|
{
|
|
63
65
|
_application = new ApplicationInstance
|
|
64
66
|
{
|
|
@@ -71,30 +73,83 @@ namespace Nodalis
|
|
|
71
73
|
{
|
|
72
74
|
ApplicationName = "NodalisServer",
|
|
73
75
|
ApplicationType = ApplicationType.Server,
|
|
74
|
-
ApplicationUri = "urn:
|
|
76
|
+
ApplicationUri = $"urn:{hostname}:NodalisServer",
|
|
75
77
|
ServerConfiguration = new ServerConfiguration
|
|
76
78
|
{
|
|
77
|
-
BaseAddresses = { "opc.tcp://
|
|
79
|
+
BaseAddresses = { $"opc.tcp://{hostname}:4840/UA/Nodalis" },
|
|
80
|
+
SecurityPolicies =
|
|
81
|
+
{
|
|
82
|
+
new ServerSecurityPolicy
|
|
83
|
+
{
|
|
84
|
+
SecurityMode = MessageSecurityMode.None,
|
|
85
|
+
SecurityPolicyUri = SecurityPolicies.None
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
UserTokenPolicies =
|
|
89
|
+
{
|
|
90
|
+
new UserTokenPolicy
|
|
91
|
+
{
|
|
92
|
+
TokenType = UserTokenType.Anonymous
|
|
93
|
+
}
|
|
94
|
+
}
|
|
78
95
|
},
|
|
79
96
|
TransportQuotas = new TransportQuotas { OperationTimeout = 15000 },
|
|
80
|
-
SecurityConfiguration =
|
|
81
|
-
{
|
|
82
|
-
ApplicationCertificate = new CertificateIdentifier(),
|
|
83
|
-
AutoAcceptUntrustedCertificates = true
|
|
84
|
-
},
|
|
97
|
+
SecurityConfiguration = CreateSecurityConfiguration(),
|
|
85
98
|
CertificateValidator = new CertificateValidator(),
|
|
86
99
|
//DiagnosticsConfiguration = new DiagnosticsConfiguration { Enabled = true },
|
|
87
100
|
Extensions = new XmlElementCollection()
|
|
88
101
|
};
|
|
89
102
|
|
|
90
103
|
await config.Validate(ApplicationType.Server);
|
|
104
|
+
await config.CertificateValidator.UpdateAsync(config, default);
|
|
91
105
|
|
|
92
106
|
_application.ApplicationConfiguration = config;
|
|
107
|
+
await _application.CheckApplicationInstanceCertificatesAsync(false, 0);
|
|
93
108
|
|
|
94
109
|
_server = new NodalisServer(_engine, _addressMap);
|
|
95
110
|
_application.Start(_server);
|
|
96
111
|
|
|
97
|
-
Console.WriteLine("OPC UA Server started at: opc.tcp://
|
|
112
|
+
Console.WriteLine($"OPC UA Server started at: opc.tcp://{hostname}:4840/UA/Nodalis");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private static SecurityConfiguration CreateSecurityConfiguration()
|
|
116
|
+
{
|
|
117
|
+
string pkiRoot = Path.Combine(AppContext.BaseDirectory, "pki");
|
|
118
|
+
string ownStore = Path.Combine(pkiRoot, "own");
|
|
119
|
+
string trustedPeerStore = Path.Combine(pkiRoot, "trusted");
|
|
120
|
+
string trustedIssuerStore = Path.Combine(pkiRoot, "issuer");
|
|
121
|
+
string rejectedStore = Path.Combine(pkiRoot, "rejected");
|
|
122
|
+
|
|
123
|
+
Directory.CreateDirectory(ownStore);
|
|
124
|
+
Directory.CreateDirectory(trustedPeerStore);
|
|
125
|
+
Directory.CreateDirectory(trustedIssuerStore);
|
|
126
|
+
Directory.CreateDirectory(rejectedStore);
|
|
127
|
+
|
|
128
|
+
return new SecurityConfiguration
|
|
129
|
+
{
|
|
130
|
+
ApplicationCertificate = new CertificateIdentifier
|
|
131
|
+
{
|
|
132
|
+
StoreType = CertificateStoreType.Directory,
|
|
133
|
+
StorePath = ownStore,
|
|
134
|
+
SubjectName = "CN=NodalisServer"
|
|
135
|
+
},
|
|
136
|
+
TrustedPeerCertificates = new CertificateTrustList
|
|
137
|
+
{
|
|
138
|
+
StoreType = CertificateStoreType.Directory,
|
|
139
|
+
StorePath = trustedPeerStore
|
|
140
|
+
},
|
|
141
|
+
TrustedIssuerCertificates = new CertificateTrustList
|
|
142
|
+
{
|
|
143
|
+
StoreType = CertificateStoreType.Directory,
|
|
144
|
+
StorePath = trustedIssuerStore
|
|
145
|
+
},
|
|
146
|
+
RejectedCertificateStore = new CertificateTrustList
|
|
147
|
+
{
|
|
148
|
+
StoreType = CertificateStoreType.Directory,
|
|
149
|
+
StorePath = rejectedStore
|
|
150
|
+
},
|
|
151
|
+
AutoAcceptUntrustedCertificates = true
|
|
152
|
+
};
|
|
98
153
|
}
|
|
99
154
|
/// <summary>
|
|
100
155
|
/// Stops the server.
|
|
@@ -222,6 +277,7 @@ namespace Nodalis
|
|
|
222
277
|
var variable = new BaseDataVariableState(folder)
|
|
223
278
|
{
|
|
224
279
|
SymbolicName = name,
|
|
280
|
+
ReferenceTypeId = ReferenceTypeIds.Organizes,
|
|
225
281
|
NodeId = new NodeId(name, NamespaceIndex),
|
|
226
282
|
BrowseName = new QualifiedName(name, NamespaceIndex),
|
|
227
283
|
DisplayName = name,
|
|
@@ -251,6 +307,7 @@ namespace Nodalis
|
|
|
251
307
|
}
|
|
252
308
|
};
|
|
253
309
|
|
|
310
|
+
folder.AddChild(variable);
|
|
254
311
|
AddPredefinedNode(SystemContext, variable);
|
|
255
312
|
}
|
|
256
313
|
}
|
|
@@ -261,6 +318,7 @@ namespace Nodalis
|
|
|
261
318
|
else if (address.Contains("X")) return _engine.ReadByte(address);
|
|
262
319
|
else if (address.Contains("W")) return _engine.ReadWord(address);
|
|
263
320
|
else if (address.Contains("D")) return _engine.ReadDWord(address);
|
|
321
|
+
else if (address.Contains("L")) return _engine.ReadLWord(address);
|
|
264
322
|
return false;
|
|
265
323
|
}
|
|
266
324
|
|
|
@@ -272,6 +330,7 @@ namespace Nodalis
|
|
|
272
330
|
case byte bt: _engine.WriteByte(address, bt); break;
|
|
273
331
|
case ushort us: _engine.WriteWord(address, us); break;
|
|
274
332
|
case uint ui: _engine.WriteDWord(address, ui); break;
|
|
333
|
+
case ulong ui64: _engine.WriteLWord(address, ui64); break;
|
|
275
334
|
default: throw new InvalidCastException($"Unsupported value type: {value?.GetType()?.Name}");
|
|
276
335
|
}
|
|
277
336
|
}
|
|
@@ -283,6 +342,7 @@ namespace Nodalis
|
|
|
283
342
|
else if (address.Contains("X")) return DataTypeIds.Byte;
|
|
284
343
|
else if (address.Contains("W")) return DataTypeIds.UInt16;
|
|
285
344
|
else if (address.Contains("D")) return DataTypeIds.UInt32;
|
|
345
|
+
else if (address.Contains("L")) return DataTypeIds.UInt64;
|
|
286
346
|
return DataTypeIds.Boolean;
|
|
287
347
|
}
|
|
288
348
|
|
|
@@ -88,6 +88,11 @@ NodalisEngine is distributed under the Apache 2.0 license. See the headers insid
|
|
|
88
88
|
|
|
89
89
|
# Changelog
|
|
90
90
|
|
|
91
|
+
## [1.0.12] - 2026-05-04
|
|
92
|
+
- Added ability to set hostname for OPCServer.
|
|
93
|
+
- Added support for LWord types to OPCServer.
|
|
94
|
+
- Fixed problems with connecting to OPCServer
|
|
95
|
+
|
|
91
96
|
## [1.0.9] - 2026-02-12
|
|
92
97
|
|
|
93
98
|
- Fixed TP function block.
|