Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function node external modules #14

Closed
spillz-dxb opened this issue Jul 15, 2022 · 7 comments
Closed

Function node external modules #14

spillz-dxb opened this issue Jul 15, 2022 · 7 comments

Comments

@spillz-dxb
Copy link

Hello!
Been trying out node-red-mcu , smaller flows doesn't take up resources.
One thing before i try , does node-red-mcu support using function nodes with external modules .
If possible one could just use scripts for rest of the npm modules ,without the need to add each node manually.
Next is trying out servers and listeners !

Good job peter and the team at node-red

@phoddie
Copy link
Owner

phoddie commented Jul 15, 2022

@spillz-dxb – thanks for giving Node-RED MCU a try.

...smaller flows doesn't take up resources...

Yes, that is very much a design goal. For this to be useful, it needs to be able to run useful flows with limited resources. So, managing those resources is a priority.

...does node-red-mcu support using function nodes with external modules

It does. But, perhaps not in the way you may imagine. There are two important differences between full Node-RED and Node-RED MCU:

  1. The Moddable SDK runtime uses standard ECMAScript Modules (ESM) not CommonJS modules, which appear to be what Node-RED uses in most cases.
  2. The Moddable SDK runtime is not Node.js, so mosts of the classes provided by Node are unavailable.

Because the Moddable SDK is not Node, I'm afraid there is no short-cut to easily re-use the existing body of Node-RED nodes as-is.

Separately, the Compatibility Node is a first attempt to implement support for running existing Node-RED modules. It works for the "lowercase" example and should work for many modules implemented without external dependencies.

Next is trying out servers and listeners !

Those aren't implemented yet. They are on the roadmap.

@spillz-dxb
Copy link
Author

Thanks peter

Separately, the Compatibility Node is a first attempt to implement support for running existing Node-RED modules. It works for the "lowercase" example and should work for many modules implemented without external dependencies.

Have tried the lower-case example, it works however the function node with external npm modules failed .
I am trying to get https://www.npmjs.com/package/node-red-contrib-bacnet and https://flows.nodered.org/node/node-red-contrib-modbus to get data in .

Would you be able to point me in the right direction please?

Next is trying out servers and listeners !

Those aren't implemented yet. They are on the roadmap.

Awaiting some inputs on the same

Glad to contribute in every way i can .

@phoddie
Copy link
Owner

phoddie commented Jul 15, 2022

@spillz-dxb – let's start with an example of the Function node using an external standard ECMAScript module from the Moddable SDK. For this example, let's use the Preference module to store state across runs.

Here's an example flow to do that.

Function node using Preference module
[
    {
        "id": "50be8a0703e59b54",
        "type": "tab",
        "label": "Flow 1",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "07ec664a0c91cd4a",
        "type": "inject",
        "z": "50be8a0703e59b54",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": true,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "",
        "payloadType": "date",
        "x": 90,
        "y": 200,
        "wires": [
            [
                "263164d2ce076cf0"
            ]
        ]
    },
    {
        "id": "263164d2ce076cf0",
        "type": "function",
        "z": "50be8a0703e59b54",
        "name": "",
        "func": "const nowSeconds = Math.round(parseInt(msg.payload) / 1000);\nconst lastRun = Preference.get(\"node-red-mcu\", \"lastRun\");\nPreference.set(\"node-red-mcu\", \"lastRun\", nowSeconds);\nif (undefined === lastRun)\n    msg.payload = \"first time\";\nelse {\n    const elapsedSeconds = nowSeconds - lastRun;\n    msg.payload = `last run ${elapsedSeconds} seconds ago`;\n}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [
            {
                "var": "Preference",
                "module": "preference"
            }
        ],
        "x": 300,
        "y": 200,
        "wires": [
            [
                "a6a95537d268828b"
            ]
        ]
    },
    {
        "id": "a6a95537d268828b",
        "type": "debug",
        "z": "50be8a0703e59b54",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": true,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 520,
        "y": 200,
        "wires": []
    }
]

To run that, you'll need to add the Preferences module to the "includes" section of node-red-mcu/manifest.json.

{
	"include": [
		...
		"$(MODDABLE)/modules/files/preference/manifest.json"
	]
	...

This technique works with any module in the Moddable SDK. Maybe give that a try to see how it works for you. Once that works, we can look at how to make some simple changes to the CommonJS modules used by the fulll Node-RED to convert them to standard ECMAScript modules so they can be imported too.

@spillz-dxb
Copy link
Author

This technique works with any module in the Moddable SDK. Maybe give that a try to see how it works for you. Once that works, we can look at how to make some simple changes to the CommonJS modules used by the fulll Node-RED to convert them to standard ECMAScript modules so they can be imported too.

image

Done!

@phoddie
Copy link
Owner

phoddie commented Aug 9, 2022

@spillz-dxb – Apologies for the delay. I've been working on a big revision to Node-RED MCU. Last night I pushed that to this repository. It has many improvements. One is that it is able to run more CommonJS modules directly. The project now includes the Delay node from the full Node-RED as an example of that. If you compare the version in the Node-RED MCU repository with the original, you'll see just a few changes to reduce memory use.

The Delay node is doesn't have any dependencies on Node.js. It is pure JavaScript plus the use of setInterval for timers. I'm not sure how many other nodes are like this. I think the Delay node might work and that it could be possible to use the full Filter node in place of my lightweight version. Maybe you can try some others from the Node-RED core or perhaps some contributed nodes? Maybe that will identify some additional work to do to make more Node-RED MCU Edition able to run more existing nodes.

@phoddie
Copy link
Owner

phoddie commented Sep 5, 2022

Next is trying out servers and listeners !

Coming back to this comment, HTTP In,HTTP Response, UDP In and UDP Out are all now available. It would be great if you can try them out. The readme describes what is (and isn't yet implemented) for the HTTP and UDP nodes.

@phoddie
Copy link
Owner

phoddie commented Oct 19, 2022

Closing this out due to inactivity.

@phoddie phoddie closed this as completed Oct 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants