Related
I have a for loop in the node red function that a the start of the function I get the array from the context
var alarmArray = flow.get("alarmArray")
and after I need to push object on the array I have do this but I'm not pusching on the flow context array but in the local array
alarmArray.push({
key: "Low air pressure",
value: alarm1Cip
});
flow.set("alarm1CipOld",alarm1Cip);
and after in the for loop I need to remove the object from the context but in my way I remove it from local array
for (var key in alarmArray){
node.warn(key);
msg.payload = {
"title": alarmArray[key].key,
"isActive":alarmArray[key].value
};
node.send(msg)
delete alarmArray[key]
}
how can I manage to add and remove object in the context array?
thanks
The problem here is that NodeJS is a pass by reference language. This means that there are not 2 arrays here, only 1 that has 2 handles (var alarmArray and flow.get('alarmArray'))
This means that anything pushed/deleted on the "local" copy is also getting pushed/deleted to the copy in the context.
The only way to do what you want will be to make a deep copy of the array every time you recover it from the context and then work on the copy locally.
Assuming the array only holds simple objects then the following should work:
var alarmArray = JSON.parse(JSON.stringify(flow.get('alarmArray')))
If you want to save your changes you just have to reload the mutated object in the right context, overwriting the previous value with
flow.set('alarmArray', alarmArray)
You might better to use global.set instead of flow.set
This might help you.
[
{
"id": "133329daaceb6bb3",
"type": "tab",
"label": "flow 3",
"disabled": false,
"info": "",
"env": []
},
{
"id": "c80bec9a15b703f6",
"type": "inject",
"z": "133329daaceb6bb3",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 140,
"y": 140,
"wires": [
[
"8687551e01cd2045"
]
]
},
{
"id": "8687551e01cd2045",
"type": "function",
"z": "133329daaceb6bb3",
"name": "msg_1",
"func": "global.set(\"msg_1\",\"test\");\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 280,
"y": 140,
"wires": [
[]
]
},
{
"id": "103b03c39c8d9cae",
"type": "debug",
"z": "133329daaceb6bb3",
"name": "debug 29",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 500,
"y": 300,
"wires": []
},
{
"id": "c043cba9f34ba574",
"type": "inject",
"z": "133329daaceb6bb3",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 140,
"y": 180,
"wires": [
[
"e674c706437cc0f3"
]
]
},
{
"id": "e674c706437cc0f3",
"type": "function",
"z": "133329daaceb6bb3",
"name": "msg_2 ",
"func": "global.set(\"msg_2\",\"hello\");\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 280,
"y": 180,
"wires": [
[]
]
},
{
"id": "11f8fb75d4c4e6c0",
"type": "inject",
"z": "133329daaceb6bb3",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "1",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 150,
"y": 300,
"wires": [
[
"1346e34e8c83b2dc"
]
]
},
{
"id": "1346e34e8c83b2dc",
"type": "function",
"z": "133329daaceb6bb3",
"name": "check if 2 msg set",
"func": "var msg1 = global.get(\"msg_1\");\nvar msg2 = global.get(\"msg_2\");\n\nif(msg1 && msg2){\n msg.payload=\"both message arrived!\";\n}\nelse{\n msg.payload=\"Nope. Not yet.\";\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 330,
"y": 300,
"wires": [
[
"103b03c39c8d9cae"
]
]
},
{
"id": "62d522a844321ef9",
"type": "inject",
"z": "133329daaceb6bb3",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 540,
"y": 140,
"wires": [
[
"6d109daff443dade"
]
]
},
{
"id": "6d109daff443dade",
"type": "function",
"z": "133329daaceb6bb3",
"name": "reset",
"func": "global.set(\"msg_1\",null);\nglobal.set(\"msg_2\",null);\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 690,
"y": 140,
"wires": [
[]
]
},
{
"id": "4e1848c867860d5f",
"type": "comment",
"z": "133329daaceb6bb3",
"name": "Here gonna auto-run",
"info": "",
"x": 170,
"y": 260,
"wires": []
},
{
"id": "3102e176923a8fad",
"type": "comment",
"z": "133329daaceb6bb3",
"name": "Check what if both inject clicked",
"info": "",
"x": 210,
"y": 100,
"wires": []
}
]
I have one system that is connected to some sensors. The main job is to send error numbers when one or more of the sensors are on.
In order to print the error description I have one csv-File with two columns, the first one with the numbers and the second one with the description.
In order to make this task I have created one flow in Node-Red:
In one line I save the array with the error numbers coming from the system in one flow variable (RandomNum).
In another line I read the csv-file with the error description, I transform it in an array of objects and then in fuction node I make a search in order to find the error number and the description.
The search function has as entance the array of objects. I save the flow variable (RandomNum) in an array (ranNum) and I define a new array (newMsg) where I save the description of the errors.
Then I use a while-loop in order to go through the array of objects and compare the value of the first column of this array with the number in ranNum. Then I save the description of the error in the array newMsg and I do this while-loop for each value of the ranNum array.
And here is my problem. When I execute the flow, it works correctly for the first value of the array ranNum but only for this. I get only the description of the first number in the ranNum array as payload, it looks like as the while-loop is used only once, and then it breaks and gives me the array newMsg.
When I check in the Conetxt, RandomNum is one array,
An when I ask to get the array ranNum, it's also an array,
I have check the while-loop at least 20-times, and I have did not found why it does not work.
Can anyone help me with this topic? Is there a problem with the flow variable or there is big difference between JavaScript and NodeJS that I did not found?
Here is the flow I have created:
[
{
"id": "b1d8b61d0ed5a5da",
"type": "tab",
"label": "Flow Test",
"disabled": false,
"info": ""
},
{
"id": "d677b342ccc51f1b",
"type": "inject",
"z": "b1d8b61d0ed5a5da",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 140,
"y": 280,
"wires": [
[
"e2d5187d2e705892",
"a167b5a81e0b36ba"
]
]
},
{
"id": "7aa6e0bcbdf67c1c",
"type": "file in",
"z": "b1d8b61d0ed5a5da",
"name": "ReadAlarms",
"filename": "/home/DMT/Dokumente/DB_Test/alarms.csv",
"format": "utf8",
"chunk": false,
"sendError": false,
"encoding": "none",
"allProps": false,
"x": 530,
"y": 280,
"wires": [
[
"f2ab599d26fd7ca5",
"94ae4b1ea29d9fe2"
]
]
},
{
"id": "f2ab599d26fd7ca5",
"type": "debug",
"z": "b1d8b61d0ed5a5da",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 750,
"y": 220,
"wires": []
},
{
"id": "94ae4b1ea29d9fe2",
"type": "csv",
"z": "b1d8b61d0ed5a5da",
"name": "ConvertAlarms",
"sep": ",",
"hdrin": false,
"hdrout": "all",
"multi": "mult",
"ret": "\\n",
"temp": "",
"skip": "0",
"strings": true,
"include_empty_strings": "",
"include_null_values": "",
"x": 760,
"y": 280,
"wires": [
[
"9a3547cc81c2d2bb",
"ff9175d01efa5ce4"
]
]
},
{
"id": "9a3547cc81c2d2bb",
"type": "debug",
"z": "b1d8b61d0ed5a5da",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 990,
"y": 220,
"wires": []
},
{
"id": "1a270df6276485c4",
"type": "debug",
"z": "b1d8b61d0ed5a5da",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 1230,
"y": 220,
"wires": []
},
{
"id": "ff9175d01efa5ce4",
"type": "function",
"z": "b1d8b61d0ed5a5da",
"name": "SearchFailureS7",
"func": "let i=0;\nlet ranNum = [];\nranNum = flow.get(\"RandomNum\");\nlet newMsg = [];\n\nwhile (i<ranNum.length){\n\n let n = ranNum[i];\n newMsg[newMsg.length] = {payload: msg.payload[n].col2};\n i = i + 1;\n \n}\n\nreturn newMsg;\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1010,
"y": 280,
"wires": [
[
"1a270df6276485c4"
]
]
},
{
"id": "a167b5a81e0b36ba",
"type": "function",
"z": "b1d8b61d0ed5a5da",
"name": "RandomArray",
"func": "const num=[];\nvar i;\n\nfor (i=0; i<3; i++){\n \nnum[i] = Math.floor(Math.random() * 9);\n\n}\n\nrandArray = {payload: num}\n\nreturn randArray;\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 340,
"y": 400,
"wires": [
[
"c011fa2387db0d18",
"9c400785174973e9"
]
]
},
{
"id": "c011fa2387db0d18",
"type": "debug",
"z": "b1d8b61d0ed5a5da",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 530,
"y": 340,
"wires": []
},
{
"id": "9c400785174973e9",
"type": "function",
"z": "b1d8b61d0ed5a5da",
"name": "",
"func": "flow.set(\"RandomNum\",msg.payload);\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 520,
"y": 400,
"wires": [
[]
]
},
{
"id": "e2d5187d2e705892",
"type": "delay",
"z": "b1d8b61d0ed5a5da",
"name": "Delay 10ms",
"pauseType": "delay",
"timeout": "10",
"timeoutUnits": "milliseconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"allowrate": false,
"outputs": 1,
"x": 330,
"y": 280,
"wires": [
[
"7aa6e0bcbdf67c1c"
]
]
}
]
So, I finally found it. The payload in the while-loop was breaking the loop immediately. So I changed the code in the while-loop using a similar code I found on the net. Now it works.
Old code:
let i=0;
let ranNum = [];
ranNum = flow.get("RandomNum");
let newMsg = [];
while (i<ranNum.length){
let n = ranNum[i];
newMsg[newMsg.length] = {payload: msg.payload[n].col2};
i = i + 1;
}
return newMsg;
New code
let i=0;
let ranNum = [];
ranNum = flow.get("RandomNum");
let newMsg = [];
while (i<ranNum.length){
let n = ranNum[i];
let description = msg.payload[n].col2;
newMsg.push(description);
i = i + 1;
}
msg.payload = newMsg;
return msg;
I use a dedicated IBM cloudant database:
When I'm retrieving values via Cloudant Query, sometimes I get multiple results with the same _id and _rev.
I thought that _id and _rev are unique values.
I post the following
"selector": {
"$and": [
{
"v": {
"$eq": 1932
}
},
{
"p": {
"$eq": "#204000102"
}
},
{
"t": {
"$lt": 1460980793,
"$gte": 1460980693
}
}
]
},
"fields": [
"_id",
"_rev",
"v",
"p",
"t",
"m",
"w"
],
"limit": 200
}
To this URL: https://user_id-bluemix.cloudant.com/status/_find
When I look at the response, I see _id 8873c90f5dbd58c58e1a7d3b9d306d09 returned twice with the same _id and _rev.
Response:
{
"docs": [
{
"_id": "9d13cffbcba60d15eeb703d0f449004d",
"_rev": "2-41e4a578dda0e3a40cb244f13f07d842",
"v": "1932",
"p": "#204000102",
"t": 1460980698,
"m": 995,
"w": true
},
{
"_id": "758ec066454846301bf2a8362fd815e4",
"_rev": "2-87c95fb7b043bb8d59740b9777e86bbe",
"v": "1932",
"p": "#204000102",
"t": 1460980764,
"m": 994,
"w": true
},
{
"_id": "8873c90f5dbd58c58e1a7d3b9d306d09",
"_rev": "2-d979563cf6a6088dbdff64e95da14b96",
"v": "1932",
"p": "#204000102",
"t": 1460980693,
"m": 994,
"w": true
},
{
"_id": "758ec066454846301bf2a8362fd815e4",
"_rev": "2-87c95fb7b043bb8d59740b9777e86bbe",
"v": "1932",
"p": "#204000102",
"t": 1460980764,
"m": 994,
"w": true
},
{
"_id": "8873c90f5dbd58c58e1a7d3b9d306d09",
"_rev": "2-d979563cf6a6088dbdff64e95da14b96",
"v": "1932",
"p": "#204000102",
"t": 1460980693,
"m": 994,
"w": true
}
],
"bookmark": "g1AAAAG1eJzLYWBgYMtgTmFQSklKzi9KdUhJMtMryE_WzcnPMzAw1EvOyS9NScwr0ctLLckBqmVKZEiS____f1YGk5uDcvh-BaBYEoNkVSiqGYZ4zUgC67KHGyN69wHYGJmDh0lxSpIDSFc83BhTNwawMRJFIiS5JgGkqx5uTOJ6iGukWu6R4po8FpDtB4AU0KT7EKNW_4W4SCyVgxQXQYx6ADEK6qpIwwZIUO9_lAUAiVOIPw"
}
Could anybody explain to me, why Cloudant sends multiple results with the same _id and _rev?
I have a DB structure as follows:
{
"Title": "AAA",
"Photos": ["/aaa/aaa.png"],
"Loc": "XXX",
"Emp": "SSS",
"Rate": [{
"Rating": 2,
"RateID": "12345654654",
"RatedDate": new Date()
}],
"Fav": [{
"FavValue": 2,
"FavID": "1111",
"FavDate": new Date()
}]
}
Here, I want to fetch all the details by default. But from array, i need to get the object that matches the ID.
In "Rate" array it needs to match "RateID" and in "Fav" array it need to match "FavID".
Both "Rate" and "Fav" wont contains objects always.
I have tried foll mongoose aggregate:
ss.aggregate([
{ $unwind: "$Rate" },
{
$group: {
"_id": '$_id',
"Title": { "$first": "$Title" },
"Loc": { "$first": "$Loc" },
"Emp": { "$first": "$Emp" },
"Photos": { "$first": "$Photos" },
"Rate": { $max: { $cond: [ { $eq: [ "$Rate.RateID", new ObjectId(id) ] }, '$Rate.Rating', null ] } },
"Fav": { $max: { $cond : [ { $eq : [{ "$size": "$Fav" }, 0]}, null, { $cond: [ { $eq: [ "$Fav.FavID", new ObjectId(id) ] }, '$Fav.FavValue', null ] } ]} }
}
}
], function (err, AvgResult) {
res.json({"result": AvgResult});
});
For "Rate", if the array is empty it returns empty result as {}
For "Fav", it returns null always if the array is empty or if it contains object
If I send the ID as '12345654654', the result should be like
{
"Title": "AAA",
"Photos": ["/aaa/aaa.png"],
"Loc": "XXX",
"Emp": "SSS",
"Rate": 2,
"Fav": null
}
If the ID is "1111", the result should be
{
"Title": "AAA",
"Photos": ["/aaa/aaa.png"],
"Loc": "XXX",
"Emp": "SSS",
"Rate": null,
"Fav": 2
}
If "Fav" is empty array in DB like "Fav": [] and ID - is "12345654654", then the result should be as follows
{
"Title": "AAA",
"Photos": ["/aaa/aaa.png"],
"Loc": "XXX",
"Emp": "SSS",
"Rate": 2,
"Fav": null
}
can any one help to get the expected result in all the above scenario..
I'm working with Elasticsearch, currently I have a struct like that
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "999999",
"_type": "content",
"_id": "NmYTku",
"_score": 1,
"_source": {
"internal_id": "NmYTk4",
"external_id": "Ga_UI502",
"
"images": [
{
"uri_id": "2939306",
"url": "14mast_head.jpg",
"type": "Masthead",
"orientation": "Landscape",
"x_resolution": 3280,
"y_resolution": 1480
},
{
"uri_id": "Galavision/POST_poster/2939306",
"url": "140603_29un_erro_poster.jpg",
"type": "Poster",
"orientation": "Portrait",
"x_resolution": 720,
"y_resolution": 405
},
{
"uri_id": "Galavision/POST_poster_title/2939306",
"url": "140603_29un_erro_poster_title.jpg",
"type": "PosterWithTitle",
"orientation": "Portrait",
"x_resolution": 924,
"y_resolution": 518
},
{
"uri_id": "Galavision/POST_poster_cover/2939306",
"url": "140603_29poster_cover.jpg",
"type": "Poster",
"orientation": "Landscape",
"x_resolution": 600,
"y_resolution": 868
}
]
}
}
]
}
}
I was wondering, how can I get only one value from my array e.g.
I want to have only the images with oritentation on Landscape and type Poster. I tried with This query but it only returns me all the image elements.
{
"query": {
"filtered": {
"filter": { "term":{"_id":"NmYTku"} }
}
},
"_source": ["images"]
}
I don't have idea how do a filter on the elements
Are you using nested or child fields for the images? If not, that doc is actually being indexed like:
...
images.uri_id = [1, 2, 3, 4, etc..]
images.url = [1, 2, 3, 4, etc..]
images.type = [1, 2, 3, 4, etc..]
...
so the distinction between individual elements is gone. Try giving this a read:
http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/complex-core-fields.html
If you don't need to query, why not just filter out the ones you like client side?
Try this:
{
"filtered": {
"query": {
"match": { "term": "_id" : "NmYTku" }
},
"_source": [images]{
"orientation": "landscape",
"type": "Poster",
}
}