Assigning values to object items

Hi folks,

I'm doing a node-red project to upload some s7 PLC variables (Siemens Simatic industrial device ET200SP CPU) to cloud.

There are a lot of variables to upload, and some of them have the same structure, so I decided to work with objects like this one: (BNBA3 is a pump motor)

var BNBA3={OnOff:0,OpTime:0,Volt:0,Amp:0};              // Pump struct
var LSA3={H:0,M:0,L:0,LAlarm:0};                                 // level status

I'm using node-red-contrib-s7. I'm working with two nodes of S7, because I have two Siemens PLC.
The S7 node output will be an array like msg.payload[0..49] (containing 50 or more variables each).

My goal is to abbreviate as maximum as possible the assignment of Siemens var values in my objects, so I'm trying to make two for loops to solve it.

This is how I planned to do it:

var i;
for (i = 0; i < msg.payload.length; i++) {
    if (i>=0 && i<=3){
    	for (var property in BNBA3){
    		$property=msg.payload[i];
    	}
    }

}

I can't test now the code, because I don't have the PLCs right now, but the doubt is if sintaxis (specially in $property line) is correct or not.

Any suggestion will be appreciated.

Best Regards,
Pau

Sure you can test it, use an inject node to simulate the data coming in and attach a debug node to the output of the function node to see what is coming out.

You could even add a node.warn() in the function node to see what is happening like this:

var i;
for (i = 0; i < msg.payload.length; i++) {
    if (i>=0 && i<=3){
    	for (var property in BNBA3){
    		$property=msg.payload[i];
               node.warn(`${property}: ${object[property]}`);
    	}
    }

}

(at least I think that node warn will work :grin:)

Thanks @zenofmud , I'll test it in that way.

A good node for arranging your PLC array into nice object / properties is the buffer-parser node. It does all the heavy lifting by taking all the effort out of looping, data typeing etc

Hi again folks,

I'm testing, but I'm not able to assign msg.payload to object values. As you can see, I recieve a buffer [ 12, 33, 26, 77, 91, 21 ], but is not assigned to a object properties values.

The code is:

var BNBA3={OnOff:0,OpTime:0,Volt:0,Amp:0};              // struct Motor
var LSA3={H:0,M:0,L:0,LAlarm:0};                        // struct water level

var i;
for (i = 0; i < msg.payload.length; i++) {
    if (i>=0 && i<=3){
    	for (var property in BNBA3){
    		property=msg.payload[i];
    	}
    }

}
global.set("BNBA3",BNBA3);

return msg;

Debug message capture of input buffer:
screenshot2

What I get in global context object:
screenshot1

It's possible to do what I want to do? If it's possible, whats the way to assign values into the object (whats wrong with my code)?

Thanks a lot to all.

Hi @pautorras

Your code does not touch the BNBA3 object, so its values will never change. To help fix it, it would be helpful to understand how you intend the buffer values [12, 33, 26, 77 ,91, 21] to be mapped into the BNBA3 object.

@pautorras
No offence intended, but that function code tells me you are a bit inexperienced with JavaScript.

So I will try one last attempt to sway you to buffer-parser.

NOTE: without knowing what bits & bytes make up those properties, I have just assigned each byte to a property (and had to add 2 bytes to the buffer).

but just to demonstrate you can avoid all this looping and manual conversion, here is a quick demo...

image

demo flow...

[{"id":"327126db.93d1ca","type":"buffer-parser","z":"4fed65e5.e87b3c","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"int8","name":"BNBA3=>OnOff","offset":0,"length":1,"offsetbit":16,"scale":"1","mask":""},{"type":"int8","name":"BNBA3=>OpTime","offset":1,"length":1,"offsetbit":16,"scale":"1","mask":""},{"type":"int8","name":"BNBA3=>Volt","offset":2,"length":1,"offsetbit":16,"scale":"1","mask":""},{"type":"int8","name":"BNBA3=>Amp","offset":3,"length":1,"offsetbit":16,"scale":"1","mask":""},{"type":"int8","name":"LSA3=>H","offset":4,"length":1,"offsetbit":16,"scale":"1","mask":""},{"type":"int8","name":"LSA3=>M","offset":5,"length":1,"offsetbit":16,"scale":"1","mask":""},{"type":"int8","name":"LSA3=>L","offset":6,"length":1,"offsetbit":16,"scale":"1","mask":""},{"type":"int8","name":"LSA3=>LAlarm","offset":7,"length":1,"offsetbit":16,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"output","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":710,"y":160,"wires":[["48b72cde.b5bbb4","91d955b3.6ef278"]]},{"id":"302044c6.a2fe3c","type":"inject","z":"4fed65e5.e87b3c","name":"PLC data (faked) [ 12, 33, 26, 77, 91, 21, 0, 0 ]","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[ 12, 33, 26, 77, 91, 21, 0, 0 ]","payloadType":"bin","x":790,"y":100,"wires":[["327126db.93d1ca"]]},{"id":"48b72cde.b5bbb4","type":"change","z":"4fed65e5.e87b3c","name":"store BNBA3 in global BNBA3","rules":[{"t":"set","p":"BNBA3","pt":"global","to":"payload.BNBA3","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":220,"wires":[[]]},{"id":"91d955b3.6ef278","type":"debug","z":"4fed65e5.e87b3c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":890,"y":160,"wires":[]}]

Hi, I would like to assign the buffer values into some objects values.
In this case, I would like to assign to object BNBA3 the firts 4 values of buffer in order 0..3.

Thanks

Okay, so I would also suggest you look at the buffer-parser node as per @Steve-Mcl 's suggestion.

But to help you understand the JavaScript a bit more, here's a bit of an explanation.

The properties of a JavaScript Object have no order - they are just named properties.
Properties of a Buffer or Array do have an order.

So you cannot say "assign the first element of the array to the first property of the object" because there is no such thing as the first property of an object.

I assume you've listed the properties of BNBA3 in the order you expect them to appear in the array passed into the function. From that, you end up with the following code:

var BNBA3={
   OnOff:  msg.payload[0],
   OpTime: msg.payload[1],
   Volt:   msg.payload[2],
   Amp:    msg.payload[3]
};
var LSA3={
   H:0,
   M:0,
   L:0,
   LAlarm:0
};

global.set("BNBA3",BNBA3);
return msg;

Thaks you all @knolleary & @Steve-Mcl for your help.
I'm a PLC programmer, and I started doing Node-Red projects 1 year ago aprox, not at full time (only when I have time), so yes, I can say that I'm not an expert with JS.

With my little experience with Node-Red and JS I found amazing the things that you can do with.
I've used Node-Red and JS to read/write PLC tags, to upload PLC tags to cloud, I've also worked with SQLite and MySQL, weather APIs, dashboard, embeed grafana in Node-Red dashboard,...

I will learn/test more about buffer-parser node because I think that is perfect for my needs. I have tested before last reply, but I've not understant at all the import samples. With @Steve-Mcl code I think I can solve my problem so thank you all again.

I love learn with you!

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.