Is there any open source OPC UA Server where i can add and configure nodes of FileType - opc-ua

I am developing a OPC UA Client Application which reads a file stored on a OPC UA Server. For testing Purpose i need a OPC UA Server simulator where i can add nodes of FileType and configure those nodes.
Currently i am using Prosys OPC UA Server Simulator where i can add a node of variable type but not of file type.

Just to be sure when it comes to a node that has a "HasTypeDefinition" reference to "FileType", it is an "Object" node (Object of type FileType) and not a "Variable" node.
I have seen reusable items in node-opcua stack and UA-.NETStandard stack to achieve what you are trying to do.
If you can spend about a day with UA-.NETStandard stack, you might be able to accomplish what you are trying to do.
ReferenceServer application in the UA-.NETStandard stack can be a good starting point.
You will have to instantiate an "Object" node of type "FileType" in the ReferenceNodeManager.cs file inside CreateAddressSpace() function definition. In a similar usecase, I have successfully instantiated an "Object" node under the Objects Folder with "HasTypeDefinition" reference to "FileType" and have used the same for File Transfer operations.
Hope this answers your question. Thank you.
If you are looking for any other hands-on information, you can check out these resources:
Free documentation: You can look at the open-source documentation page: https://open62541.org/doc/current/
Paid online course: Practical introduction to OPC UA – code walk-through and examples in this course use the open62541 stack: https://opcfoundation.org/products/view/practical-introduction-to-opc-ua-part-i

You should try with the new version 5 of Prosys OPC UA Simulation Server. It enables you to add objects of any type - although it doesn't let you configure any files behind the FileType.
For that, you could just try the Prosys OPC UA SDK for Java. The free evaluation version comes with a sample server that can serve files as well. (And yes, I work for Prosys OPC...)

If you need a fully functional OPCUA server that exposes a File Node from which you can actually read and write, you can achieve this easily using node-opcua and the following script:
import {
OPCUAServer,
UAFileType,
StatusCodes,
Variant,
CallMethodResultOptions,
SessionContext,
} from "node-opcua";
import { installFileType, getFileData } from "node-opcua-file-transfer";
import { callbackify } from "util";
import * as fs from "fs";
const my_data_filename = "/tmp/someFile.txt";
fs.writeFileSync(my_data_filename, "some content", "utf8");
(async () => {
try {
const server = new OPCUAServer({
port: 26540,
});
await server.initialize();
// now add a file object in the address Space
const addressSpace = server.engine.addressSpace;
const namespace = addressSpace.getOwnNamespace();
// retrieve the FileType UAObjectType
const fileType = addressSpace.findObjectType("FileType")!;
// create a instance of FileType
const opcuaFile = fileType.instantiate({
nodeId: "s=MyFile",
browseName: "MyFile",
organizedBy: addressSpace.rootFolder.objects,
}) as UAFileType;
// now bind the opcuaFile object with our file
installFileType(opcuaFile, {
filename: my_data_filename,
});
await server.start();
console.log("Server is now listening on port 26540.. ( press CTRL+C to stop)");
} catch (err) {
console.log("err", err);
}
})();
More examples can be found in https://leanpub.com/node-opcuabyexample

Related

Working with URL parameters in custom Kibana plugin

I am working on a custom plugin to Kibana (7.5.2). The plugin is of type 'app'. I would like to be able to pass parameters to this plugin in order to pre-load some data from Elasticsearch. I.e., I need to provide users with some specific URLs containing parameters that will be used by the plugin to show only a relevant portion of data.
My problem is that I was not able to find sufficient documentation on this and I do not know what the correct approach should be. I will try to summarize what I know/have done so far:
I have read the official resources on plugin development
I am aware of the fact that _g and _a URL parameters are used to pass state in Kibana applications. However, a) I am not sure if this is the correct approach in my case and b) I also failed to find any information on how my plugin should access the data from these parameters.
I checked the sources of other known plugins, but again, failed to find any clues.
I am able to inject some configuration values using injectUiAppVars in the init method of my plugin (index.js) and retrieve these values in my app (main.js):
index.js:
export default function (kibana) {
return new kibana.Plugin({
require: ['elasticsearch'],
name: ...,
uiExports: {
...
},
...
init(server, options) { // eslint-disable-line no-unused-vars
server.injectUiAppVars('logviewer', async () => {
var kibana_vars = await server.getInjectedUiAppVars('kibana');
var aggregated_vars = { ...kibana_vars, ...{ mycustomparameter: "some value" } }
return aggregated_vars
});
...
}
});
}
main.js
import chrome from 'ui/chrome';
. . .
const mycustomparameter = chrome.getInjected('mycustomparameter');
Providing that I manage to obtain parameters from URL, this would allow me to pass them to my app (via mycustomparameter), but again, I am not sure if this approach is correct.
I tried to get some help via the Elastic forum, but did not receive any answer yet.
My questions
1. Is there any source of information on this particular topic? I am aware of the fact that the plugin API changes frequently, hence I do not expect to find an extensive documentation. Maybe a good example?
Am I completely off course with the way I am trying to achieve it?
Thanks for reading this, any help would be much appreciated!

MQTT connection creation and subscribe

I'm setting up a new mqtt conection in my app but there is a problem when i would like to create the main connection of mqtt.
I'm using mqtt.js.
I've tried all what is done in MQTT documentation but nothing happens..
mqttFunction(){
var mqtt = require('mqtt');
var client = mqtt.connect([{host: 'localhost', port: '1883'},]);
client.subscribe('presence')
client.on('message', function (topic, message) {
console.log(message);
});
}
I expect the output of the mqtt broker to be 'ON' when i asked it to respond.
The error is: ERROR ReferenceError: process is not defined
The documentation you followed is intended for Node.js and various other back-end JavaScript frameworks. Even though it uses NPM, Ionic ultimately produces a front-end framework, and its applications run a bit differently.
For example, Ionic programs may not have a global process variable like Node.js. mqtt.js expects this variable, with code like:
if (commist.parse(process.argv.slice(2)) !== null){...}
You could declare a process object, and get past this particular error. Other obstacles could come up.
var process = {env : {NODE_ENV: 'production'}}
If there are still issues with that, you could try the instructions for browser usage, which point to a specially compiled version, like https://unpkg.com/mqtt#3.0.0/dist/mqtt.min.js. I have had less luck with mqtt.js in the browser, and you may want an alternative like web-mqtt-cient / Paho if more complex connections are involved.

Differentiating an "admin" level access for a node in Milo OPC UA project?

While trying to understand the milo project examples for OPC UA based client and server, wanted to get clarified on the following scenario.
When I was trying to test WriteExample with namespace string HelloWorld/OnlyAdminCanWrite/
to connect with server which validates the user with UserNameIdentityToken values "admin" (username) and password2 (password), it was not able to write values.
Is it because the identity is not recognized as admin as seen in the following code in the ExampleNamespace.java file?
node.setAttributeDelegate(new RestrictedAccessDelegate(identity -> {
if ("admin".equals(identity)) {
return AccessLevel.READ_WRITE;
} else {
return AccessLevel.READ_ONLY;
}
How to differentiate the admin from the other users? tested attributes like AccessLevel and UserAccessLevel but they are effective on the current user trying to access.
Thank you for the clarification. Yes you are right, I was using the wrong NodeId. The right NodeId is "HelloWorld/OnlyAdminCanWrite/String" and in order to test WriteExample the Variant value to be written should be a String. Now it works !

Connect external language server to VSCode extension

I want to implement a VSCode extension that uses the Language Server Protocol, but I want the server component to be on an actual server (in the cloud), and not a part of the VSCode extension.
Can I set the client extension to connect to a server via websockets or HTTP?
Multiple ServerOptions are supported when you initialize a LanguageClient according to the signature of ServerOptions.
you can use the StreamInfo if you want to use a real remove server as your language server. Here is a sample code to connect to your server via WebSocket and initialize a LanguageClient.
const connection = connectToServer(hostname, path);
const client = new LanguageClient(
"docfxLanguageServer",
"Docfx Language Server",
() => Promise.resolve<StreamInfo>({
reader: connection,
writer: connection,
}),
{});
private connectToServer(hostname: string, path: string): Duplex {
const ws = new WebSocket(`ws://${hostname}/${path}`);
return WebSocket.createWebSocketStream(ws);
}
I am not sure if you can control the location of the language server, but there is another option. You do not need to implement the Language Server Protocol to, for example, provide parsing help. In that case you can implement your own convenient parsing service API (tailored to the nature of the language you want to support).
Within your extension you subscribe to workspace edit events using workspace.onDidChangeTextDocument
Re-start a 1sec timeout every time the file on-change event is raised
When the timeout expires without any further file modification, gather all relevant files and send them to your parsing server
In your extension, create a DiagnosticCollection using https://code.visualstudio.com/api/references/vscode-api#languages.createDiagnosticCollection and replace populate it with the warnings/errors/hints resulting from the parsing server in the cloud.
Subscribe to other workspace events, e.g. workspace.onDidOpenTextDocument or workspace.onDidCloseTextDocument in order to keep the DiagnosticCollection content relevant

IPython Javascript client API

Does IPython provide a Javascript client API for interfacing to a kernel server?
I had a look at https://ipython.org/ipython-doc/dev/development/messaging.html which explains the wire protocol between a front-end and a kernel.
I would be interested in finding out how the current web client communicates with a kernel and in particular how I could leverage JavaScript in order to programmatically create new notebooks from my own custom web client
Thanks
See https://gist.github.com/disarticulate/d06069ff3e71cf828e5329beab8cb084
There you can see a nice example:
// a very basic output handling
var handle_output = function (data) {console.log(data);}
//callbacks is an object whose so special, it appears to only have been documented in
//the source code, as no only google found me a link.
//callbacks.iopub.output is used to get the data from execute
var callbacks = {
iopub : {
output : handle_output,
}
}
//execute anything you want; if a string value is returned
//you can print it out and pass it to the callbacks
//(or do other things, no idea, it's poorly documented online
//(read the source F12->static/notebook/js/services/kernels/kernel.js)
//kernel.js/Kernel.prototype.execute
var kernel = IPython.notebook.kernel;
kernel.execute("print(json.dumps(python_dict))",callbacks)
You can see the definition going to in /static/services/kernels/kernel.js