-
Notifications
You must be signed in to change notification settings - Fork 0
/
flows_CNERT2018.json
1 lines (1 loc) · 70.2 KB
/
flows_CNERT2018.json
1
[{"id":"dfca7471.a1e698","type":"tab","label":"single-hop_WSN"},{"id":"9e87c9ce.0ab558","type":"subflow","name":"final_action","info":"","in":[{"x":160,"y":160,"wires":[{"id":"3972ce6c.855b12"},{"id":"f6d3eb40.3d072"}]}],"out":[]},{"id":"7823bf3e.a929f","type":"subflow","name":"Measurement","info":"","in":[{"x":120,"y":100,"wires":[{"id":"2b087b64.ee4304"}]}],"out":[{"x":940,"y":240,"wires":[{"id":"ed0ef637.615ba8","port":0}]},{"x":980,"y":600,"wires":[{"id":"8e46b0fc.31eca","port":0}]},{"x":940,"y":280,"wires":[{"id":"c26cb2.cecd835","port":0}]}]},{"id":"88bd6d14.13a9f","type":"subflow","name":"param_config","info":"","in":[{"x":100,"y":100,"wires":[{"id":"d45b4dbc.e56cb"}]}],"out":[{"x":880,"y":80,"wires":[{"id":"fa9e8a50.158288","port":0}]}]},{"id":"bf1a2f25.59371","type":"subflow","name":"cooja setup","info":"","in":[{"x":60,"y":100,"wires":[{"id":"163eca94.272855"}]}],"out":[{"x":840,"y":360,"wires":[{"id":"64ac6270.65c05c","port":0}]}]},{"id":"1e47311c.96e34f","type":"debug","z":"9e87c9ce.0ab558","name":"action_stdout","active":true,"console":"false","complete":"true","x":650,"y":220,"wires":[]},{"id":"422359ef.8e2e38","type":"function","z":"dfca7471.a1e698","name":"Experiment Setup","func":"\n// Resource controller identifier\ncontext.global.RC_ID = 1;\n\n// Get coordinates of IMEC w-ilab.t sensor nodes\nfunction ID_to_cord(ID)\n{ var cord = {};\n\tswitch(ID)\n\t{\n\t\tcase 1: cord = {X: 6.0, Y: 2.0}; break;\tcase 22: cord = {X: 6.0, Y: 9.2 }; break;\tcase 43: cord = {X: 6.0, Y: 16.4}; break;\n\t\tcase 2: cord = {X: 12.0, Y: 2.0}; break;\tcase 23: cord = {X: 12.0, Y: 9.2 }; break;\tcase 44: cord = {X: 12.0, Y: 16.4}; break;\n\t\tcase 3: cord = {X: 18.0, Y: 2.0}; break;\tcase 24: cord = {X: 18.0, Y: 9.2 }; break;\tcase 45: cord = {X: 18.0, Y: 16.4}; break;\n\t\tcase 4: cord = {X: 24.0, Y: 2.0}; break;\tcase 25: cord = {X: 24.0, Y: 9.2 }; break;\tcase 46: cord = {X: 24.0, Y: 16.4}; break;\n\t\tcase 5: cord = {X: 30.0, Y: 2.0}; break;\tcase 26: cord = {X: 30.0, Y: 9.2 }; break;\tcase 47: cord = {X: 30.0, Y: 16.4}; break;\n\t\tcase 6: cord = {X: 36.0, Y: 2.0}; break;\tcase 27: cord = {X: 36.0, Y: 9.2 }; break;\tcase 48: cord = {X: 36.0, Y: 16.4}; break;\n\t\tcase 7: cord = {X: 42.0, Y: 2.0}; break;\tcase 28: cord = {X: 42.0, Y: 9.2 }; break;\tcase 49: cord = {X: 42.0, Y: 16.4}; break;\n\t\tcase 8: cord = {X: 48.0, Y: 2.0}; break;\tcase 29: cord = {X: 48.0, Y: 9.2 }; break;\tcase 50: cord = {X: 48.0, Y: 16.4}; break;\n\t\tcase 9: cord = {X: 54.0, Y: 2.0}; break;\tcase 30: cord = {X: 54.0, Y: 9.2 }; break;\tcase 51: cord = {X: 54.0, Y: 16.4}; break;\n\t\tcase 10: cord = {X: 60.0, Y: 2.0}; break;\tcase 31: cord = {X: 60.0, Y: 9.2 }; break;\tcase 52: cord = {X: 60.0, Y: 16.4}; break;\n\t\tcase 11: cord = {X: 6.0, Y: 5.6}; break;\tcase 33: cord = {X: 6.0, Y: 12.8}; break;\n\t\tcase 12: cord = {X: 12.0, Y: 5.6}; break;\tcase 34: cord = {X: 12.0, Y: 12.8}; break;\tcase 53: cord = {X: 12.0, Y: 20.0}; break;\n\t\tcase 13: cord = {X: 18.0, Y: 5.6}; break;\tcase 35: cord = {X: 18.0, Y: 12.8}; break;\tcase 54: cord = {X: 18.0, Y: 20.0}; break;\n\t\tcase 14: cord = {X: 24.0, Y: 5.6}; break;\tcase 36: cord = {X: 24.0, Y: 12.8}; break;\n\t\tcase 15: cord = {X: 30.0, Y: 5.4}; break;\tcase 37: cord = {X: 30.0, Y: 12.8}; break;\tcase 55: cord = {X: 30.0, Y: 20.0}; break;\n\t\tcase 16: cord = {X: 36.0, Y: 5.5}; break;\tcase 38: cord = {X: 36.0, Y: 12.8}; break;\tcase 56: cord = {X: 36.0, Y: 20.0}; break;\n\t\tcase 17: cord = {X: 42.0, Y: 5.5}; break;\tcase 39: cord = {X: 42.0, Y: 12.8}; break;\tcase 57: cord = {X: 42.0, Y: 20.0}; break;\n\t\tcase 18: cord = {X: 48.0, Y: 5.5}; break;\tcase 40: cord = {X: 48.0, Y: 12.8}; break;\tcase 58: cord = {X: 48.0, Y: 20.0}; break;\n\t\tcase 19: cord = {X: 54.0, Y: 5.5}; break;\tcase 41: cord = {X: 54.0, Y: 12.8}; break;\tcase 59: cord = {X: 54.0, Y: 20.0}; break;\n\t\tcase 20: cord = {X: 60.0, Y: 5.5}; break;\tcase 42: cord = {X: 60.0, Y: 12.8}; break;\tcase 60: cord = {X: 60.0, Y: 20.0}; break;\n\t}\n\treturn cord;\n}\n// IMEC w-ilab.t Testbed\n// ┌─────────────────────────────────────────────────────────────────────┐\n// │ 1 2 3 4 5 6 7 8 9 10 │\n// │ 11 12 13 14 15 16 17 18 19 20 │\n// │ 22 23 24 25 26 27 28 29 30 31 │\n// │ 33 34 35 36 37 38 39 40 41 42 │\n// │ 43 44 45 46 47 48 49 50 51 52 │\n// │ 53 54 55 56 57 58 59 60 │\n// └─────────────────────────────────────────────────────────────────────┘\n\nvar sink_ID = [ 27 ];\nvar source_ID = [ 16, 26, 28, 38 ];\nvar disturber_ID = [ 56 ];\n\n\n// ******* Do not change beyond this line ******* //\n// nodes used in the experiment\nvar GROUPs = {};\n// Sink node group definition\nGROUPs.sink = [];\nGROUPs.sink.push({ID: sink_ID[0], loc: ID_to_cord(sink_ID[0])});\n// Source nodes group definition\nGROUPs.source = [];\nfor(var i=0; i<source_ID.length; i++)\n{\n GROUPs.source.push({ID: source_ID[i], loc: ID_to_cord(source_ID[i])});\n}\n// Disturber nodes group definition\nGROUPs.disturber = [];\nfor(var i=0; i<disturber_ID.length; i++)\n{\n GROUPs.disturber.push({ID: disturber_ID[i], loc: ID_to_cord(disturber_ID[i])});\n}\n\n// Make nodes and ids global\ncontext.global.GROUPs = GROUPs;\n\n// Convert integer to hexadecimal of given size\ncontext.global.int2hex = function (integer, size)\n{\n\t// Is the passed value an integer\n\tif(Number.isInteger(integer) === true)\n\t{\n\t\tvar buf = Buffer.allocUnsafe(4);\n\t\t// 8 bit integer\n\t\tif(size == 1)\n\t\t{\n\t\t\tvar uint8 = new Uint8Array([integer]);\n\t\t\tbuf.writeUInt8(uint8[0], 0);\n\t\t}\n\t\t// 16 bit integer\n\t\telse if(size == 2)\n\t\t{\n\t\t\tvar uint16 = new Uint16Array([integer]);\n\t\t\tbuf.writeUInt16LE(uint16[0], 0);\n\t\t}\n\t\t// Else, use 32 bit integer\n\t\telse\n\t\t{\n\t\t\tsize = 4;\n\t\t\tvar uint32 = new Uint32Array([integer]);\n\t\t\tbuf.writeUInt32LE(uint32[0], 0);\n\t\t}\n\t\treturn buf.toString('hex', 0, size);\n\t}\n\telse\n\t{\n\t\tconsole.error(\"int2hex: \" + integer + \" is not an integer\");\n\t}\n};\n\nreturn msg;\n","outputs":1,"noerr":0,"x":190,"y":280,"wires":[["224cdeb4.09de02"]]},{"id":"feca1dc3.2391e","type":"comment","z":"dfca7471.a1e698","name":"Experiment Setup + Initialization","info":"In this part of the experiment, initial configuraton and setting up of the experiment is conducted.\n\nAt the end of this phase, the experimentation setup will be in a known state with all default parameters configured.","x":170,"y":180,"wires":[]},{"id":"cc8c849.715ac78","type":"comment","z":"dfca7471.a1e698","name":"Initial parameter settings","info":"","x":610,"y":200,"wires":[]},{"id":"f995d8d8.0d4328","type":"function","z":"dfca7471.a1e698","name":"Radio Parameters","func":"\n// Group of nodes global variable\nvar GROUPs = context.global.GROUPs;\n\n// Radio UIDs\nvar UID =\n{\n phy_channel : 14751,\n phy_txPower : 28244,\n cca_threshold : 6819,\n cycleTime : 43299,\n ccaRxCountMax : 26072,\n ccaTxCountMax : 5735\n};\n\n// Variable types\nvar UINT_T = 0;\nvar INT_T = 1;\n\n// Configurable parameters\nvar phy_channel = 27; // zigbee channel\nvar phy_txPower = 5; // transmission power in dBm\nvar cca_threshold = -80; // CCA threshold in dBm\nvar cycleTime = 65536; // contikiMAC cycle time usec\nvar ccaRxCountMax = 3; // Rx CCA max Count\nvar ccaTxCountMax = 5; // Tx CCA max Count\n\n// Default radio parameters\nvar radio_parameters = \n[\n // Set parameters on sink and source nodes\n {\n GROUPs: [GROUPs.sink, GROUPs.source],\n control_hdr:\n [ \n { uid: UID.phy_channel, type: UINT_T, len: 1, value : phy_channel },\n { uid: UID.phy_txPower, type: INT_T, len: 1, value : phy_txPower },\n { uid: UID.cca_threshold, type: INT_T, len: 1, value : cca_threshold },\n { uid: UID.cycleTime, type: UINT_T, len: 4, value : cycleTime },\n { uid: UID.ccaRxCountMax, type: UINT_T, len: 1, value : ccaRxCountMax },\n { uid: UID.ccaTxCountMax, type: UINT_T, len: 1, value : ccaTxCountMax }\n ]\n }\n];\n\n// ******* Do not change beyond this line ******* //\nvar msg = {};\nmsg.parameters = radio_parameters;\nmsg.topic = \"radio_configuration\";\n\nreturn msg;","outputs":1,"noerr":0,"x":600,"y":280,"wires":[["85a1f8ea.f70828"]]},{"id":"ceb87228.3f744","type":"comment","z":"dfca7471.a1e698","name":"BFS occurrences","info":"","x":120,"y":680,"wires":[]},{"id":"57500133.1a477","type":"comment","z":"dfca7471.a1e698","name":"Intelligent experimentation","info":"","x":150,"y":420,"wires":[]},{"id":"658babd1.b88c94","type":"function","z":"dfca7471.a1e698","name":"PUT","func":"\n// Group of nodes global variable\nvar GROUPs = context.global.GROUPs;\n\n// PUT UIDs\nvar UID =\n{\n Tx_channel : 14751,\n Tx_power : 28244,\n CCA_THLD : 6819,\n cycleTime : 43299,\n CCA_RxMax : 26072,\n CCA_TxMax : 5735,\n send_interval : 19367,\n message_size : 57215,\n Retx_max : 46644,\n INT_DY : 45201\n};\n\nvar UINT_T = 0;\nvar INT_T = 1;\n\n// Parameters Under Test\nvar PUT = \n[\n {\n GROUPs: [GROUPs.sink, GROUPs.source],\n opcode: 1,\n control_hdr:\n [\n { name: \"Tx_channel\", uid: UID.Tx_channel, type: UINT_T, len: 1, values : [10, 18, 26] }, // Tranmission channel number\n { name: \"Tx_power\", uid: UID.Tx_power, type: INT_T, len: 1, values : [-4, -2, 0, 2, 4] }, // Tranmission power level in dBm\n { name: \"CCA_THLD\", uid: UID.CCA_THLD, type: INT_T, len: 1, values : [-95, -80, -65] }, // Clear channel assesment threshold in dBm\n { name: \"cycleTime\", uid: UID.cycleTime, type: UINT_T, len: 4, values : [32768, 65536, 98304, 131072] }, // contiki-MAC cycle time in usec\n { name: \"CCA_RxMax\", uid: UID.CCA_RxMax, type: UINT_T, len: 1, values : [2, 3, 4, 5] }, // Maximum # of receive CCA checks\n { name: \"CCA_TxMax\", uid: UID.CCA_TxMax, type: UINT_T, len: 1, values : [4, 5, 6, 7] }, // Maximum # of transmit CCA checks\n { name: \"send_interval\", uid: UID.send_interval, type: UINT_T, len: 4, values : [768, 1536, 2304] }, // Interference duty cycle percentage\n { name: \"message_size\", uid: UID.message_size, type: UINT_T, len: 1, values : [50, 75, 100] }, // Application message size in bytes\n { name: \"Retx_max\", uid: UID.Retx_max, type: UINT_T, len: 1, values : [0, 1, 2, 3, 4] } // Maximum # of packet retransmission before reporting failure\n\n ]\n },\n {\n GROUPs: [GROUPs.disturber],\n opcode: 1,\n control_hdr:\n [\n { name: \"INT_DY\", uid: UID.INT_DY, type: UINT_T, len: 1, values : [0, 5, 10, 15, 20] } // Interference duty cycle percentage\n ]\n }\n];\n\n// Save PUT as a global variable\ncontext.global.PUT = PUT;\n\n// Global sample index\ncontext.global.sample_Idx = 0;\n\nmsg = {};\nmsg.PUT = PUT;\nmsg.topic = \"start_experiment\";\n//msg.topic = \"restart_experiment\";\n\nmsg.sample_Idx = context.global.sample_Idx;\nmsg.port = context.global.pts_mux_port;\nreturn msg;","outputs":1,"noerr":0,"x":150,"y":520,"wires":[["c10eea79.85a57"]]},{"id":"628d5c69.bb29a4","type":"subflow:7823bf3e.a929f","z":"dfca7471.a1e698","name":"","x":630,"y":520,"wires":[["ca5b04e9.7dd678"],["77e261e.1fa302"],["a0f16bee.b00f58"]]},{"id":"e08b2ee5.d7ded","type":"subflow:9e87c9ce.0ab558","z":"dfca7471.a1e698","name":"","x":170,"y":720,"wires":[]},{"id":"b4478f18.78109","type":"comment","z":"dfca7471.a1e698","name":"Planning","info":"","x":300,"y":480,"wires":[]},{"id":"74da1545.132bcc","type":"comment","z":"dfca7471.a1e698","name":"Reasoning","info":"","x":820,"y":480,"wires":[]},{"id":"adc47910.160cc8","type":"comment","z":"dfca7471.a1e698","name":"Execution","info":"","x":460,"y":480,"wires":[]},{"id":"d490cced.0bfc","type":"function","z":"dfca7471.a1e698","name":"Application Parameters","func":"\n// Group of nodes global variable\nvar GROUPs = context.global.GROUPs;\n\n// Application UIDs\nvar UID = \n{\n send_interval : 19367,\n message_size : 57215,\n Retx_max : 46644,\n receiver : 57217,\n source_IDs : 57218,\n activate_app : 25440\n};\n\n// Variable types\nvar UINT_T = 0;\nvar INT_T = 1;\n\n// Configurable parameters\nvar send_interval = 768; // sending interval in ticks [128 ticks === 1 sec]\nvar message_size = 100; // message size\nvar Retx_max = 2; // maximum retransmission\nvar sink_ID = GROUPs.sink[0].ID; // Receiver ID\nvar source_IDs = []; // source IDs\nfor(var i = 0; i < GROUPs.source.length; i++)\n source_IDs.push(GROUPs.source[i].ID);\n\n// Make sending interval a global parameter\ncontext.global.send_interval = send_interval;\n\n// Default application parameters\nvar app_parameters = \n[\n // Set parameters on sink nodes\n {\n GROUPs: [GROUPs.sink],\n control_hdr:\n [\n { uid: UID.Retx_max, type: UINT_T, len: 1, value : Retx_max },\n { uid: UID.receiver, type: UINT_T, len: 2, value : sink_ID },\n { uid: UID.source_IDs, type: UINT_T, len: 2, value : source_IDs },\n { uid: UID.activate_app, type: UINT_T, len: 1, value : 1 }\n ]\n },\n // Set parameters on source nodes\n {\n GROUPs: [GROUPs.source],\n control_hdr:\n [\n { uid: UID.send_interval, type: UINT_T, len: 4, value : send_interval},\n { uid: UID.message_size, type: UINT_T, len: 1, value : message_size },\n { uid: UID.Retx_max, type: UINT_T, len: 1, value : Retx_max },\n { uid: UID.receiver, type: UINT_T, len: 2, value : sink_ID },\n { uid: UID.source_IDs, type: UINT_T, len: 2, value : source_IDs },\n { uid: UID.activate_app, type: UINT_T, len: 1, value : 1 }\n ]\n }\n];\n\nvar msg = {};\nmsg.parameters = app_parameters;\nmsg.topic = \"app_configuration\";\n\nreturn msg;","outputs":1,"noerr":0,"x":610,"y":240,"wires":[["85a1f8ea.f70828"]]},{"id":"9264f556.824c38","type":"function","z":"dfca7471.a1e698","name":"Custom Parameters","func":"\n// Group of nodes global variable\nvar GROUPs = context.global.GROUPs;\n\n// Custom UIDs\nvar UID = \n{\n intr_period : 45200,\n intr_dutyCycle : 45201\n};\n\n// Variable types\nvar UINT_T = 0;\nvar INT_T = 1;\n\n// configurable parameters\nvar intr_period = 40000; // Interference period in usec\nvar intr_dutyCycle = 0; // Interference duty cycle percentage\n\n// Custom parameters\nvar custom_parameters = \n[\n // Set parameters on disturber nodes\n {\n GROUPs: [GROUPs.disturber],\n control_hdr:\n [\n { uid: UID.intr_period, type: UINT_T, len: 4, value : intr_period },\n { uid: UID.intr_dutyCycle, type: UINT_T, len: 1, value : intr_dutyCycle }\n ]\n }\n];\n\nvar msg = {};\nmsg.parameters = custom_parameters;\nmsg.topic = \"custom_configuration\";\n\nreturn msg;","outputs":1,"noerr":0,"x":600,"y":320,"wires":[["85a1f8ea.f70828"]]},{"id":"c26cb2.cecd835","type":"link in","z":"7823bf3e.a929f","name":"stderr","links":["f59ec35d.47189","f800d3dc.43e82","25922f09.f9abb","27fe6cb0.8612a4"],"x":755,"y":280,"wires":[[]]},{"id":"f800d3dc.43e82","type":"link out","z":"7823bf3e.a929f","name":"stderr","links":["c26cb2.cecd835"],"x":695,"y":280,"wires":[]},{"id":"dd3393f9.97be","type":"link in","z":"7823bf3e.a929f","name":"delay_in","links":["b2332f43.08231"],"x":115,"y":440,"wires":[["614f3a7b.531ea4"]]},{"id":"b2332f43.08231","type":"link out","z":"7823bf3e.a929f","name":"delay_in","links":["dd3393f9.97be"],"x":695,"y":320,"wires":[]},{"id":"354cb8d0.974f78","type":"comment","z":"7823bf3e.a929f","name":"Reset statistic variables","info":"","x":280,"y":240,"wires":[]},{"id":"b7383a3f.5f47d8","type":"function","z":"7823bf3e.a929f","name":"Retrv","func":"\n// Control opcode enumeration\nvar UID =\n{\n TXSTATS : 57219,\n RXSTATS : 57216,\n ENERGESTSTATS : 57220\n};\n\n// Default application parameters\nvar GROUPs = context.global.GROUPs;\nvar sink_ptsFile = GROUPs.sink[0].ptsFile;\nvar source_ptsFiles = [];\nfor(var i = 0; i < GROUPs.source.length; i++)\n source_ptsFiles.push(GROUPs.source[i].ptsFile);\n\nvar parameters = [];\nfor(var i = 0; i < source_ptsFiles.length; i++)\n{\n var ptsFile = source_ptsFiles[i];\n\n // Retrieve txStats parameters on source nodes\n var tx_parameter =\n {\n ptsFile: ptsFile,\n opcode: 0,\n control_hdr:\n [\n { uid: UID.TXSTATS, type: 0xFF, len: 6 }\n ]\n };\n parameters.push(tx_parameter);\n \n // Retrieve rxStats parameters on sink nodes\n // Search for sender ID from the given pts device file path\n for(var j = 0; j < GROUPs.source.length; j++)\n {\n if(ptsFile == GROUPs.source[j].ptsFile)\n {\n // senser ID is sent through the type attribute of control_hdr structure\n sender_ID = GROUPs.source[j].ID;\n \n var rx_parameter =\n {\n ptsFile: sink_ptsFile,\n opcode: 0,\n control_hdr:\n [\n { uid: UID.RXSTATS, type: sender_ID, len: 10 }\n ]\n };\n parameters.push(rx_parameter);\n \n break;\n }\n }\n \n // Retrieve energest parameters on source nodes\n var energest_parameter =\n {\n ptsFile: ptsFile,\n opcode: 0,\n control_hdr:\n [\n { uid: UID.ENERGESTSTATS, type: 0xFF, len: 16 }\n ]\n };\n parameters.push(energest_parameter);\n}\n \n// Retrieve energest parameters on sink node\nvar energest_parameter =\n{\n ptsFile: sink_ptsFile,\n opcode: 0,\n control_hdr:\n [\n { uid: UID.ENERGESTSTATS, type: 0xFF, len: 16 }\n ]\n};\nparameters.push(energest_parameter);\n\nmsg.payload = parameters;\nmsg.port = context.global.pts_mux_port;\n\nreturn msg;\n\n","outputs":1,"noerr":0,"x":230,"y":600,"wires":[["655a6ecf.d0d2a"]]},{"id":"bfa8825a.f8078","type":"comment","z":"7823bf3e.a929f","name":"Retrieve statistic variables","info":"","x":290,"y":560,"wires":[]},{"id":"7c74086a.613078","type":"link out","z":"7823bf3e.a929f","name":"delay_out","links":["b2935017.a41c"],"x":555,"y":420,"wires":[]},{"id":"b2935017.a41c","type":"link in","z":"7823bf3e.a929f","name":"delay_out","links":["7c74086a.613078"],"x":115,"y":600,"wires":[["b7383a3f.5f47d8"]]},{"id":"f59ec35d.47189","type":"link out","z":"7823bf3e.a929f","name":"stderr","links":["c26cb2.cecd835"],"x":695,"y":660,"wires":[]},{"id":"647c15b2.de598c","type":"link in","z":"7823bf3e.a929f","name":"reset_in","links":["59f98fab.12ff"],"x":115,"y":280,"wires":[["bc25892c.d242e8"]]},{"id":"59f98fab.12ff","type":"link out","z":"7823bf3e.a929f","name":"reset_in","links":["647c15b2.de598c"],"x":375,"y":140,"wires":[]},{"id":"2b087b64.ee4304","type":"function","z":"7823bf3e.a929f","name":"PUT check","func":"\n// PUT execution request/response payload and error\nvar payload = msg.payload;\nvar error_msg = msg.error_msg;\n\n// Iterate through all request/response parameters and\n// 1. retrieve PUT parameter values\n// 2. verify that values are successfully executed [\"00\"]\nvar PUT_params = {};\nfor(var i = 0; i < payload.length; i++)\n{\n var request = payload[i].request;\n var response = payload[i].response;\n \n var resp_control_hdr = response.control_hdr;\n for(var j = 0; j < resp_control_hdr.length; j++)\n {\n // Is a parameter executed successfully?\n if(resp_control_hdr[j].value === \"00\")\n {\n\t\t\tresp_control_hdr.splice(j, 1);\n\t\t\tj--;\n }\n }\n \n // Display errors\n if(resp_control_hdr.length !== 0)\n {\n error_msg.push({request: request, response: response});\n }\n else\n {\n var req_control_hdr = request.control_hdr;\n for(var j = 0; j < req_control_hdr.length; j++)\n {\n var uid = req_control_hdr[j].uid;\n // Do not include active radio program reloading parameter\n if(uid !== 28170)\n {\n var type = req_control_hdr[j].type;\n var len = req_control_hdr[j].len;\n var value;\n \n // UINT_T\n if(type === 0)\n value = Buffer.from(req_control_hdr[j].value, 'hex').readUIntLE(0, len);\n // INT_T\n else if(type === 1)\n value = Buffer.from(req_control_hdr[j].value, 'hex').readIntLE(0, len);\n \n PUT_params[uid] = value;\n }\n }\n }\n}\n\n// delete PUT execution request/response payload\ndelete msg.payload;\n \n// Do we have an error message\nif(error_msg.length !== 0)\n{\n msg.sample_Idx = context.global.sample_Idx;\n return [msg, {payload: error_msg}, null];\n}\n// Experiment execution has passed\nelse\n{\n // Save PUT parameters for later use\n context.global.PUT_params = PUT_params;\n\t\n return [null, null, msg];\n}","outputs":"3","noerr":0,"x":250,"y":100,"wires":[["7ad86a1e.c42ba4"],["25922f09.f9abb"],["59f98fab.12ff"]]},{"id":"25922f09.f9abb","type":"link out","z":"7823bf3e.a929f","name":"stderr","links":["c26cb2.cecd835"],"x":375,"y":100,"wires":[]},{"id":"15bb44f4.c909db","type":"comment","z":"7823bf3e.a929f","name":"Wait before collecting results","info":"","x":300,"y":400,"wires":[]},{"id":"f6036096.b398","type":"function","z":"7823bf3e.a929f","name":"reset check","func":"\n// PUT execution request/response payload and error\nvar payload = msg.payload;\nvar error_msg = msg.error_msg;\n\n// Iterate through all request/response parameters and verify that values are successfully executed [\"00\"]\nfor(var i = 0; i < payload.length; i++)\n{\n var request = payload[i].request;\n var response = payload[i].response;\n \n var control_hdr = response.control_hdr;\n \n for(var j = 0; j < control_hdr.length; j++)\n {\n // Is a parameter executed successfully?\n if(control_hdr[j].value === \"00\")\n {\n\t\t\tcontrol_hdr.splice(j, 1);\n\t\t\tj--;\n }\n }\n \n // Display errors\n if(control_hdr.length !== 0)\n error_msg.push({request: request, response: response});\n}\n\n// delete PUT execution request/response payload\ndelete msg.payload;\n \n// Do we have an error message\nif(error_msg.length !== 0)\n{\n msg.sample_Idx = context.global.sample_Idx;\n return [msg, {payload: error_msg}, null];\n}\n// Experiment execution has passed\nelse\n{\n return [null, null, msg];\n}","outputs":"3","noerr":0,"x":570,"y":280,"wires":[["66498699.415548"],["f800d3dc.43e82"],["b2332f43.08231"]]},{"id":"66498699.415548","type":"link out","z":"7823bf3e.a929f","name":"redo_experiment","links":["e33aa464.db8818"],"x":695,"y":240,"wires":[]},{"id":"7ad86a1e.c42ba4","type":"link out","z":"7823bf3e.a929f","name":"redo_experiment","links":["e33aa464.db8818"],"x":375,"y":60,"wires":[]},{"id":"e33aa464.db8818","type":"link in","z":"7823bf3e.a929f","name":"redo_experiment","links":["66498699.415548","7ad86a1e.c42ba4","25413c89.512fa4"],"x":755,"y":240,"wires":[["ed0ef637.615ba8"]]},{"id":"25413c89.512fa4","type":"link out","z":"7823bf3e.a929f","name":"redo_experiment","links":["e33aa464.db8818"],"x":695,"y":540,"wires":[]},{"id":"277f5f2a.bf33d","type":"comment","z":"7823bf3e.a929f","name":"redo experiment","info":"","x":1060,"y":240,"wires":[]},{"id":"33f7b98c.723016","type":"comment","z":"7823bf3e.a929f","name":"error message","info":"","x":1050,"y":280,"wires":[]},{"id":"16591027.57894","type":"comment","z":"7823bf3e.a929f","name":"experiment passed","info":"","x":1110,"y":600,"wires":[]},{"id":"d562d571.3d70b8","type":"link in","z":"dfca7471.a1e698","name":"experiment_setup","links":["cad5031f.ce83b","78729d33.d2d714"],"x":55,"y":280,"wires":[["422359ef.8e2e38"]]},{"id":"5d7a5c2e.85f964","type":"link in","z":"dfca7471.a1e698","name":"PUT","links":["72a6250f.461e0c","f588c087.1ce03"],"x":55,"y":520,"wires":[["658babd1.b88c94"]]},{"id":"67232339.a0ba8c","type":"link in","z":"dfca7471.a1e698","name":"action","links":["d3e95180.f9e2b","1aa0e54a.3fa1db","cf320c23.2bd3d","9c93a6b7.ba11f8","570f448.32383bc"],"x":55,"y":720,"wires":[["e08b2ee5.d7ded"]]},{"id":"f588c087.1ce03","type":"link out","z":"dfca7471.a1e698","name":"reasoning","links":["5d7a5c2e.85f964"],"x":955,"y":280,"wires":[]},{"id":"570f448.32383bc","type":"link out","z":"dfca7471.a1e698","name":"reasoning","links":["67232339.a0ba8c"],"x":955,"y":520,"wires":[]},{"id":"5f39396e.667518","type":"link in","z":"dfca7471.a1e698","name":"planning","links":["620458e1.f98428","f666e010.4f7c1","ca5b04e9.7dd678"],"x":175,"y":480,"wires":[["c10eea79.85a57"]]},{"id":"1c66ecc.ac53013","type":"UPI_exec","z":"dfca7471.a1e698","name":"PUT Exec","host":"127.0.0.1","port":"6200","timeout":"10000","retry":"3","reload_MAC":true,"x":460,"y":520,"wires":[["628d5c69.bb29a4"]]},{"id":"82ebe0aa.f1317","type":"UPI_exec","z":"7823bf3e.a929f","name":"Reset Exec","host":"127.0.0.1","port":"6200","timeout":"10000","retry":"3","reload_MAC":false,"x":390,"y":280,"wires":[["f6036096.b398"]]},{"id":"655a6ecf.d0d2a","type":"UPI_exec","z":"7823bf3e.a929f","name":"Retrv Exec","host":"127.0.0.1","port":"6200","timeout":"10000","retry":"3","reload_MAC":false,"x":390,"y":600,"wires":[["25bd72f4.2afabe"]]},{"id":"25bd72f4.2afabe","type":"function","z":"7823bf3e.a929f","name":"centr_output","func":"\n// Function to calculate the current consumption (mA) of CC2520 radio chip for different Transmit power settings\nfunction TXdBm2mA(TXdBm)\n{\n if(TXdBm == -18) return 10.2; else if(TXdBm == -7) return 15.3;\n else if(TXdBm == -4) return 18.4; else if(TXdBm == -2) return 22.1;\n else if(TXdBm === 0) return 25.8; else if(TXdBm === 1) return 26.7;\n else if(TXdBm === 2) return 27.9; else if(TXdBm === 3) return 29.5;\n else if(TXdBm === 5) return 33.6; else return 33.6;\n}\n\n// Function to generate sampleSet header string\nfunction gen_sampleSet_hdr_str()\n{\n\tvar PUT_array = context.global.PUT;\n\t\n var values_obj = {};\n\tfor(var i = 0; i < PUT_array.length; i++)\n\t{\n\t\t// Retreive global PUT variable\n\t\tvar PUT = PUT_array[i];\n\t\tfor (var j = 0; j < PUT.control_hdr.length; j++)\n\t\t{\n\t\t\t// Sort values in ascending order\n\t\t\tvar uid = PUT.control_hdr[j].uid;\n\t\t\tvalues_obj[uid] = PUT.control_hdr[j].values.sort(function(a, b){return a - b;});\n\t\t}\n\t}\n\t\n\tvar lower_bound = \"\";\n\tvar upper_bound = \"\";\n\tvar steps = \"\";\n\tfor(var key in values_obj)\n\t{\n\t var values = values_obj[key];\n\t \n\t\t// Calculate step width\n\t\tvar step = 0;\n\t\tif(values.length == 1)\n\t\t{\n\t\t\tstep = values[0];\n\t\t}\n\t\telse if(values.length > 1)\n\t\t{\n\t\t\tvar array_sum = values.reduce(function (a, b) {return a + b;}, 0);\n\t\t\tstep = 2*(array_sum - values.length * values[0]) / ( values.length * (values.length - 1) );\n\t\t}\n\n\t\tlower_bound = lower_bound + values[0] + \",\";\n\t\tupper_bound = upper_bound + values[values.length - 1] + \",\";\n\t\tsteps = steps + step + \",\";\n\t}\n\tlower_bound = lower_bound.slice(0, -1);\n\tupper_bound = upper_bound.slice(0, -1);\n\tsteps = steps.slice(0, -1);\n\n\treturn \"[ \" + lower_bound + \" ; \" + upper_bound + \" ; \" + steps + \" ]\";\n}\n\n\n// Function to calculate average of an array\nfunction AVG(data)\n{\n\tif(data.length === 0)\n\t\treturn 0;\n\telse\n\t return (data.reduce(function (a,b) { return a+b; }) / data.length);\n}\n\n// Retreive PUT parameters\nvar PUT_params = context.global.PUT_params;\nvar sampleSet_array = [];\nfor (var key in PUT_params)\n sampleSet_array.push(PUT_params[key]);\n\n// Retrieve error message\nvar error_msg = msg.error_msg;\n\n// Do we have an error message\nif(error_msg.length !== 0)\n{\n msg = {};\n msg.sample_Idx = context.global.sample_Idx;\n msg.payload = sampleSet_array;\n return [msg, null, null, {payload: error_msg}];\n}\nelse\n{\n // Control opcode enumeration\n var UID =\n {\n TXSTATS : 57219,\n RXSTATS : 57216,\n ENERGESTSTATS : 57220\n };\n \n var GROUPs = context.global.GROUPs;\n var sink_ptsFile = GROUPs.sink[0].ptsFile;\n \n // Sample index\n var sample_Idx = context.global.sample_Idx;\n \n var payload = msg.payload;\n var LAT_array = [];\n var PER_array = [];\n var Energy_sink = 0;\n var Energy_source = 0;\n for(var i = 0; i < payload.length; i++)\n {\n var ptsFile = payload[i].request.ptsFile;\n var response = payload[i].response;\n var num_param = response.num_param;\n \n // We expect one message\n if(num_param === 1)\n {\n var control_hdr = response.control_hdr[0];\n var uid = control_hdr.uid;\n \n // TxStat message\n if(uid === UID.TXSTATS)\n {\n var value = Buffer.from(control_hdr.value, 'hex');\n \n var latency_sum = value.readUInt32LE(0);\n var latency_count = value.readUInt16LE(4);\n\n // Calculate performance objectives\n LAT_array.push(parseFloat(latency_sum / (1000*latency_count)));\n }\n // RxStat message\n else if(uid === UID.RXSTATS)\n {\n var value = Buffer.from(control_hdr.value, 'hex');\n \n var packet_recvd = value.readUInt16LE(4);\n var packet_lost = value.readUInt16LE(6);\n \n // Calculate performance objectives\n if(packet_recvd > 0)\n PER_array.push(parseFloat(100 * packet_lost/(packet_lost + packet_recvd)));\n else\n PER_array.push(100.0);\n }\n // Energest message\n else if(uid === UID.ENERGESTSTATS)\n {\n var value = Buffer.from(control_hdr.value, 'hex');\n \n var Tx_mA = TXdBm2mA(5);\n var TX_energy = (value.readUInt32LE(0)/1000000) * Tx_mA * 3;\n var LST_energy = (value.readUInt32LE(4)/1000000) * 22.3 * 3;\n var IDLE_energy = (value.readUInt32LE(8)/1000000) * 1.6 * 3;\n var SLEEP_energy = (value.readUInt32LE(12)/1000000) * 0.175 * 3;\n \n // Sink node\n if(ptsFile === sink_ptsFile)\n Energy_sink += TX_energy + LST_energy + IDLE_energy + SLEEP_energy;\n // source nodes\n else\n Energy_source += TX_energy + LST_energy + IDLE_energy + SLEEP_energy;\n }\n }\n }\n // Calculate average Lateny and PER\n var LAT_avg = AVG(LAT_array);\n var PER_avg = AVG(PER_array);\n \n // Make sure all objectives are numbers\n if(isNaN(LAT_avg) || isNaN(PER_avg) || isNaN(Energy_sink) || isNaN(Energy_source))\n {\n msg = {};\n msg.sample_Idx = sample_Idx;\n msg.payload = sampleSet_array;\n error_msg = \"At least one objective value is NaN. LAT_avg=\" + LAT_avg + \" PER_avg=\" + PER_avg + \" Energy_sink=\" + Energy_sink + \" Energy_source=\" + Energy_source;\n return [msg, null, null, {payload: error_msg}];\n }\n else\n {\n // Formulate objective string\n var obj_str = LAT_avg + \"\\t\" + PER_avg + \"\\t\" + Energy_sink + \"\\t\" + Energy_source;\n \n var sampleSet_str = \"\";\n // First message includes sampleSet header\n if(sample_Idx === 0)\n sampleSet_str = gen_sampleSet_hdr_str() + \"\\n\";\n // Add dataset string\n sampleSet_str = sampleSet_str + sampleSet_array.join('\\t') + \"\\t\" + obj_str;\n \n // MOSBO file path and sampleSet string\n msg.payload = [{filename: \"/root/samplesValues.txt\", payload: sampleSet_str}];\n msg.sample_Idx = sample_Idx;\n delete msg.error_msg;\n \n // Update sample index\n context.global.sample_Idx = sample_Idx + 1;\n \n if(sample_Idx === 0)\n return [null, msg, null, null];\n else\n return [null, null, msg, null];\n }\n}\n","outputs":"4","noerr":0,"x":570,"y":600,"wires":[["25413c89.512fa4"],["98509978.45f6b8"],["c1e616dc.c824d8"],["f59ec35d.47189"]]},{"id":"8b109a79.481828","type":"comment","z":"dfca7471.a1e698","name":"Collection","info":"","x":620,"y":480,"wires":[]},{"id":"bc25892c.d242e8","type":"function","z":"7823bf3e.a929f","name":"Reset","func":"\n// Control opcode enumeration\nvar UID =\n{\n TXSTATS : 57219,\n RXSTATS : 57216,\n ENERGESTSTATS : 57220\n};\n\n// Default application parameters\nvar GROUPs = context.global.GROUPs;\nvar sink_ptsFile = GROUPs.sink[0].ptsFile;\nvar source_ptsFiles = [];\nfor(var i = 0; i < GROUPs.source.length; i++)\n source_ptsFiles.push(GROUPs.source[i].ptsFile);\n\n// Integer to hexadicimal string convertor\nvar int2hex = context.global.int2hex;\n\nvar parameters = [];\nfor(var i = 0; i < source_ptsFiles.length; i++)\n{\n var ptsFile = source_ptsFiles[i];\n\n // Reset TxStat parameters\n var latency_sum_hex = int2hex(0, 4);\n var latency_count_hex = int2hex(0, 2);\n \n var txstats_value = latency_sum_hex + latency_count_hex;\n var txstats_len = txstats_value.length / 2;\n var tx_parameter = \n {\n ptsFile: ptsFile,\n opcode: 1,\n control_hdr:\n [\n { uid: UID.TXSTATS, type: 0xFF, len: txstats_len, value: txstats_value }\n ]\n };\n parameters.push(tx_parameter);\n\n // Reset RxStat parameters \n var sender_ID;\n var rxstats_value = \"\";\n // Search for sender ID from the given pts device file path\n for(var j = 0; j < GROUPs.source.length; j++)\n {\n if(ptsFile == GROUPs.source[j].ptsFile)\n {\n // senser ID is sent through the type attribute of control_hdr structure\n sender_ID = GROUPs.source[j].ID;\n \n var rssi_sum_hex = int2hex(0, 2);\n var lqi_sum_hex = int2hex(0, 2);\n var packet_recvd_hex = int2hex(0, 2);\n var packet_lost_hex = int2hex(0, 2);\n\n rxstats_value = rssi_sum_hex + lqi_sum_hex + packet_recvd_hex + packet_lost_hex;\n break;\n }\n }\n var rxstats_len = rxstats_value.length / 2;\n var rx_parameter = \n {\n ptsFile: sink_ptsFile,\n opcode: 1,\n control_hdr:\n [\n { uid: UID.RXSTATS, type: sender_ID, len: rxstats_len, value: rxstats_value }\n ]\n };\n parameters.push(rx_parameter);\n \n // Reset energest parameters on source nodes\n var energest_parameter =\n {\n ptsFile: ptsFile,\n opcode: 1,\n control_hdr:\n [\n { uid: UID.ENERGESTSTATS, type: 0xFF, len: 1, value: \"FF\" }\n ]\n };\n parameters.push(energest_parameter);\n}\n\n// Reset energest parameters on sink node\nvar energest_parameter =\n{\n ptsFile: sink_ptsFile,\n opcode: 1,\n control_hdr:\n [\n { uid: UID.ENERGESTSTATS, type: 0xFF, len: 1, value: \"FF\" }\n ]\n};\nparameters.push(energest_parameter);\n\n\n\n// ******* Do not change beyond this line ******* //\nmsg.payload = parameters;\nmsg.port = context.global.pts_mux_port;\n\nreturn msg;\n\n","outputs":1,"noerr":0,"x":230,"y":280,"wires":[["82ebe0aa.f1317"]]},{"id":"98509978.45f6b8","type":"Mfile_out","z":"7823bf3e.a929f","name":"1st msg","appendNewline":true,"overwriteFile":"true","x":740,"y":580,"wires":[["8e46b0fc.31eca"]]},{"id":"c1e616dc.c824d8","type":"Mfile_out","z":"7823bf3e.a929f","name":"rmn msg","appendNewline":true,"overwriteFile":"false","x":740,"y":620,"wires":[["8e46b0fc.31eca"]]},{"id":"f04a5251.eb484","type":"inject","z":"dfca7471.a1e698","name":"Start","topic":"start_experiment","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":110,"y":80,"wires":[["78729d33.d2d714"]]},{"id":"78729d33.d2d714","type":"link out","z":"dfca7471.a1e698","name":"experiment_setup","links":["d562d571.3d70b8"],"x":215,"y":80,"wires":[]},{"id":"614f3a7b.531ea4","type":"function","z":"7823bf3e.a929f","name":"10 packet delay","func":"\n// packet count to be sent\nvar packet_count = 10;\n\n// Sending interval in usec\nvar send_interval_ticks = context.global.send_interval; \nvar send_interval_usec = send_interval_ticks * 1000000 / 128;\n\n// Wait until [packet_count] packets are sent\nvar delay_usec = packet_count * send_interval_usec + 10000;\n\nmsg.payload = delay_usec.toString() + \"\\n\";\n\n// If simTimer port exists as a global variable\nif(typeof(context.global.simTimer_port) !== \"undefined\")\n msg.port = context.global.simTimer_port;\n\nreturn msg;","outputs":1,"noerr":0,"x":260,"y":440,"wires":[["85e538ae.291218"]]},{"id":"85e538ae.291218","type":"tcpClient","z":"7823bf3e.a929f","name":"simTimer","host":"127.0.0.1","port":"7700","timeout":"800000","client_disconnects":false,"x":440,"y":440,"wires":[["7c74086a.613078"],["27fe6cb0.8612a4"]]},{"id":"8e46b0fc.31eca","type":"split","z":"7823bf3e.a929f","name":"","splt":"\\n","x":890,"y":600,"wires":[[]]},{"id":"27fe6cb0.8612a4","type":"link out","z":"7823bf3e.a929f","name":"stderr","links":["c26cb2.cecd835"],"x":555,"y":460,"wires":[]},{"id":"ed0ef637.615ba8","type":"delay","z":"7823bf3e.a929f","name":"delay","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":850,"y":240,"wires":[[]]},{"id":"3972ce6c.855b12","type":"exec","z":"9e87c9ce.0ab558","command":"killall java ; killall pts_mux","addpay":false,"append":"","useSpawn":"","timer":"","oldrc":true,"name":"Stop APPs","x":290,"y":220,"wires":[[],["1e47311c.96e34f"],[]]},{"id":"dddd50c4.346e9","type":"link out","z":"dfca7471.a1e698","name":"planning_error","links":["5f4a2077.c42f2"],"x":415,"y":580,"wires":[]},{"id":"a0f16bee.b00f58","type":"link out","z":"dfca7471.a1e698","name":"collection_error","links":["5f4a2077.c42f2"],"x":775,"y":580,"wires":[]},{"id":"5f4a2077.c42f2","type":"link in","z":"dfca7471.a1e698","name":"stderr","links":["1b935ea9.7984e1","a0f16bee.b00f58","dddd50c4.346e9","620458e1.f98428","ca5b04e9.7dd678","f666e010.4f7c1","c1740649.64a018","74776db6.e6f2f4"],"x":875,"y":580,"wires":[["eedfe88b.bb6c28"]]},{"id":"eedfe88b.bb6c28","type":"debug","z":"dfca7471.a1e698","name":"stderr","active":true,"console":"false","complete":"true","x":990,"y":580,"wires":[]},{"id":"d45b4dbc.e56cb","type":"function","z":"88bd6d14.13a9f","name":"combine_param","func":"\n// Convert integer to hexadecimal of given size\nvar int2hex = context.global.int2hex;\n\n// Update parameters to default state\nvar parameters = msg.parameters;\nvar payload = [];\nfor(var i = 0; i < parameters.length; i++)\n{\n var groups = parameters[i].GROUPs;\n var control_hdr_orig = parameters[i].control_hdr;\n \n // Update control header values\n var control_hdr = [];\n for(var j = 0; j < control_hdr_orig.length; j++)\n {\n var uid = control_hdr_orig[j].uid;\n var type = control_hdr_orig[j].type;\n var len_orig = control_hdr_orig[j].len;\n var value_orig = control_hdr_orig[j].value;\n\n var value = \"\";\n var len = 0;\n \n // original value is a number\n if(typeof(value_orig) == \"number\")\n {\n value = int2hex(value_orig, len_orig);\n \tlen = len_orig;\n }\n // original value is a string\n else if(typeof(value_orig) == \"string\")\n {\n for(var k = 0; k < value_orig.length; k++)\n {\n \t value = value + value_orig.charCodeAt(k);\n len ++;\n }\n }\n // original value is an array or an object\n else if(typeof(value_orig) == \"object\")\n {\n for(var k in value_orig)\n {\n // original value is a number\n if(typeof(value_orig[k]) == \"number\")\n {\n value = value + int2hex(value_orig[k], len_orig);\n \tlen = len + len_orig;\n }\n // original value is a string\n else if(typeof(value_orig[k]) == \"string\")\n {\n for(var l = 0; l < value_orig[k].length; l++)\n {\n \t value = value + value_orig[k].charCodeAt(l);\n len ++;\n }\n }\n // original value is an array or an object\n else if(typeof(value_orig[k]) == \"object\")\n {\n for(var l in value_orig[k])\n {\n \t value = value + int2hex(value_orig[k][l], len_orig);\n \t len = len + len_orig;\n }\n }\n }\n }\n control_hdr.push({uid: uid, type: type, len: len, value : value});\n }\n\n // Update group of nodes\n for(var j = 0; j < groups.length; j++)\n {\n var nodes = groups[j];\n \tvar node_count = Object.keys(nodes).length;\n \tfor(var k = 0; k < node_count; k++)\n \t{\n \t var ptsFile = nodes[k].ptsFile;\n \t \n \t payload.push({ptsFile : ptsFile, opcode : 1, control_hdr : control_hdr});\n \t}\n }\n}\n\nif(msg.topic == \"app_configuration\")\n{\n context.app_configuration = payload;\n}\nelse if(msg.topic == \"radio_configuration\")\n{\n context.radio_configuration = payload;\n}\nelse if(msg.topic == \"custom_configuration\")\n{\n context.custom_configuration = payload;\n}\n\nif(typeof(context.app_configuration) !== \"undefined\" && typeof(context.radio_configuration) !== \"undefined\" && typeof(context.custom_configuration) !== \"undefined\")\n{\n var configurations = context.radio_configuration.concat(context.app_configuration.concat(context.custom_configuration));\n\n // Bind identical ptsFile request configurations\n for(var i = 0; i < configurations.length; i++)\n {\n // Search remaining configurations having similar ptsFiles and similar opcodes\n for(var j = i+1; j < configurations.length; j++)\n {\n if((configurations[i].ptsFile == configurations[j].ptsFile) && (configurations[i].opcode == configurations[j].opcode))\n {\n configurations[i].control_hdr = configurations[i].control_hdr.concat(configurations[j].control_hdr);\n configurations.splice(j,1);\n j--;\n }\n }\n }\n\n msg = {};\n msg.payload = configurations;\n msg.topic = \"start_experiment\";\n msg.port = context.global.pts_mux_port;\n\n // Reset context parameters for next round\n delete context.app_configuration;\n delete context.radio_configuration;\n delete context.custom_configuration;\n\n return msg;\n}\n\n","outputs":1,"noerr":0,"x":240,"y":100,"wires":[["22e0a6fd.c91a5a"]]},{"id":"777b198f.579888","type":"function","z":"88bd6d14.13a9f","name":"default check","func":"\n// PUT execution request/response payload\nvar payload = msg.payload;\nvar error_msg = msg.error_msg;\n\n// Iterate through all request/response parameters and verify that values are successfully executed [\"00\"]\nfor(var i = 0; i < payload.length; i++)\n{\n var request = payload[i].request;\n var response = payload[i].response;\n \n var control_hdr = response.control_hdr;\n for(var j = 0; j < control_hdr.length; j++)\n {\n // Are parameters executed successfully?\n if(control_hdr[j].value === \"00\")\n {\n\t\t\tcontrol_hdr.splice(j, 1);\n\t\t\tj--;\n }\n }\n \n // Display errors\n if(control_hdr.length !== 0)\n error_msg.push({request: request, response: response});\n}\n\n// delete PUT execution request/response payload\ndelete msg.payload;\n \n// Do we have an error message\nif(error_msg.length !== 0)\n{\n return [null, {payload: error_msg}];\n}\n// Experiment execution has passed\nelse\n{\n return [{payload: context.global.RC_ID}, null];\n}","outputs":"2","noerr":0,"x":610,"y":100,"wires":[["fa9e8a50.158288"],["cedc6785.865d18"]]},{"id":"22e0a6fd.c91a5a","type":"UPI_exec","z":"88bd6d14.13a9f","name":"Default Exec","host":"127.0.0.1","port":"6200","timeout":"10000","retry":"3","reload_MAC":true,"x":430,"y":100,"wires":[["777b198f.579888"]]},{"id":"fa9e8a50.158288","type":"delay","z":"88bd6d14.13a9f","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":780,"y":80,"wires":[[]]},{"id":"85a1f8ea.f70828","type":"subflow:88bd6d14.13a9f","z":"dfca7471.a1e698","name":"","x":830,"y":280,"wires":[["f588c087.1ce03"]]},{"id":"f666e010.4f7c1","type":"link out","z":"dfca7471.a1e698","name":"reasoning","links":["5f39396e.667518","5f4a2077.c42f2"],"x":955,"y":440,"wires":[]},{"id":"cedc6785.865d18","type":"debug","z":"88bd6d14.13a9f","name":"stderr","active":true,"console":"false","complete":"true","x":770,"y":120,"wires":[]},{"id":"751c0d1d.8e48d4","type":"function","z":"bf1a2f25.59371","name":"check","func":"\nvar msg1 = {};\nvar msg2 = {};\n\n// Empty payload => cooja is not started\nif(msg.payload === \"\")\n{\n msg.payload = \"ERROR: cooja simulation is not started\";\n return [null, null, msg];\n}\nelse\n{\n var ptyFiles_IDs = msg.payload.split('\\n').filter(function(e){return e;});\n var ptyFiles = [];\n for(var i = 0; i < ptyFiles_IDs.length; i++)\n ptyFiles.push(ptyFiles_IDs[i].split('\\t')[1]);\n\n return [{payload: ptyFiles_IDs}, {payload: ptyFiles.join(',')}, null];\n}","outputs":"3","noerr":0,"x":350,"y":400,"wires":[["2b5e2c3e.0754d4"],["b9705e75.dcab3"],["2edc926e.29303e"]]},{"id":"53cd833.6b2737c","type":"comment","z":"bf1a2f25.59371","name":"Retrieve pts devices","info":"","x":130,"y":360,"wires":[]},{"id":"163eca94.272855","type":"function","z":"bf1a2f25.59371","name":"cooja csc template","func":"// Retrieve extention name of a path\nfunction extName(path)\n{\n return path.substring(path.lastIndexOf('.') + 1); \n}\n\n// Retrieve base name of a path\nfunction baseName(path)\n{\n var base = path.substring(path.lastIndexOf('/') + 1); \n if(base.lastIndexOf(\".\") != -1) \n base = base.substring(0, base.lastIndexOf(\".\"));\n return base;\n}\n\n// Retrieve directory name of a path\nfunction dirName(path)\n{\n var dir = \"\";\n if(path.lastIndexOf('/') != -1)\n dir = path.substring(0, path.lastIndexOf('/'));\n else\n dir = path;\n return dir;\n}\n\n// choose simulation mode [non_gui/gui]\nvar simulation_mode = \"non_gui\";\n\n// Unit Disk Graph radio Medium (UDGM)\nvar UDGM = {};\nUDGM.name = \"UDGM\";\nUDGM.transmitting_range = \"80.0\";\nUDGM.interference_range = \"120.0\";\nUDGM.success_ratio_tx = \"1.0\";\nUDGM.success_ratio_rx = \"0.5\";\n\n// Multi-path Ray-tracing radio Medium (MRM)\nvar MRM = {};\nMRM.name = \"MRM\";\nMRM.snr_threshold = 6;\nMRM.bg_noise_mean = -100;\nMRM.bg_noise_var = 1;\nMRM.rx_sensitivity = -100;\nMRM.rt_max_rays = 8;\nMRM.rt_max_refractions = 5;\nMRM.rt_max_reflections = 5;\nMRM.rt_max_diffractions = 0;\nMRM.rt_refrac_coefficient = -3;\nMRM.rt_reflec_coefficient = -5;\nMRM.rt_diffr_coefficient = -10;\nMRM.obstacle_attenuation = -3;\nMRM.obstacles = [[0, 0, 18, 0.25],\n [0, 3.75, 18, 0.25],\n [0, 0.25, 0.25, 3.5],\n [17.75, 0.25, 0.25, 3.5],\n [8, 0.875, 2, 0.25],\n [8, 2.875, 2, 0.25],\n [8.875, 1.5, 0.25, 1]];\n\n// Select radio medium to use\nvar radiomedium = UDGM;\n\nvar title = \"single-hop_WSN\";\nvar CONTIKI_DIR = \"/root/contiki\";\nvar firm_path_rel = \"examples/rime/single-hop_WSN.rm090\";\nvar firm_path_CONTIKI = \"[CONTIKI_DIR]/\" + firm_path_rel;\nvar platform = extName(firm_path_rel);\n\n// Cooja contiki parameters\nvar contiki_log = \"COOJA.contikilog\";\nvar contiki_done_str = \"taiscmac nullrdc, channel check rate\";\n\nvar simconf = \n[\n {name: \"simulation\", children:\n [\n {name: \"title\", text: title},\n// {name: \"speedlimit\", text: \"1.0\"},\n {name: \"randomseed\", text: \"generated\"},\n {name: \"motedelay_us\", text: \"1000000\"},\n {name: \"events\", children: \n [\n {name: \"logoutput\", text: \"40000\"}\n ]},\n ]}\n];\n\n// Simulation array\nvar sim_array = simconf[0].children;\n\n// Unit Disk Graph Radio Medium (UDGM)\nif(radiomedium.name === \"UDGM\")\n{\n sim_array.push({name: \"radiomedium\", text: \"org.contikios.cooja.radiomediums.UDGM\", children: \n [\n {name: \"transmitting_range\", text: radiomedium.transmitting_range},\n {name: \"interference_range\", text: radiomedium.interference_range},\n {name: \"success_ratio_tx\", text: radiomedium.success_ratio_tx},\n {name: \"success_ratio_rx\", text: radiomedium.success_ratio_rx}\n ]});\n}\n// Multi-path Ray-tracing radio medium (MRM)\nelse if(radiomedium.name === \"MRM\")\n{\n sim_array.push({name: \"radiomedium\", text: \"org.contikios.mrm.MRM\", children: \n [\n {name: \"snr_threshold\", attrs: {value: radiomedium.snr_threshold}},\n {name: \"bg_noise_mean\", attrs: {value: radiomedium.bg_noise_mean}},\n {name: \"bg_noise_var\", attrs: {value: radiomedium.bg_noise_var}},\n {name: \"rx_sensitivity\", attrs: {value: radiomedium.rx_sensitivity}},\n {name: \"rt_max_rays\", attrs: {value: radiomedium.rt_max_rays}},\n {name: \"rt_max_refractions\", attrs: {value: radiomedium.rt_max_refractions}},\n {name: \"rt_max_reflections\", attrs: {value: radiomedium.rt_max_reflections}},\n {name: \"rt_max_diffractions\", attrs: {value: radiomedium.rt_max_diffractions}},\n {name: \"rt_refrac_coefficient\", attrs: {value: radiomedium.rt_refrac_coefficient}},\n {name: \"rt_reflec_coefficient\", attrs: {value: radiomedium.rt_reflec_coefficient}},\n {name: \"rt_diffr_coefficient\", attrs: {value: radiomedium.rt_diffr_coefficient}},\n {name: \"obstacle_attenuation\", attrs: {value: radiomedium.obstacle_attenuation}},\n {name: \"obstacles\"}\n ]});\n \n if(typeof(radiomedium.obstacles) !== \"undefined\")\n {\n // Obstacles object\n var radiomedium_array = sim_array[sim_array.length-1].children;\n var obstacles_obj = radiomedium_array[radiomedium_array.length-1];\n \n // Obstacles array\n obstacles_obj.children = [];\n var obstacles_array = obstacles_obj.children;\n for(var i = 0; i < radiomedium.obstacles.length; i++)\n {\n var obstacle_str = radiomedium.obstacles[i][0];\n for(var j = 1; j < radiomedium.obstacles[i].length; j++)\n obstacle_str = obstacle_str + \";\" + radiomedium.obstacles[i][j];\n \n obstacles_array.push({name: \"obst\", text: obstacle_str});\n }\n \n }\n}\n\n// Create mote configuration\nvar GROUPs = context.global.GROUPs;\n\n// Solution Under Test (SUT) motetype configuration\nif(GROUPs.sink.length > 0 || GROUPs.source.length > 0)\n{\n sim_array.push({name: \"motetype\", text: \"org.contikios.cooja.mspmote.\" + platform.toUpperCase() + \"MoteType\", children:\n [\n {name: \"identifier\", text: platform + \"1\"},\n {name: \"description\", text: platform + \" Mote Type #\" + platform},\n {name: \"firmware\", text: firm_path_CONTIKI, attrs: {EXPORT: \"copy\"}},\n [\n {name: \"moteinterface\", text: \"org.contikios.cooja.interfaces.Position\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.interfaces.RimeAddress\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.interfaces.IPAddress\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.interfaces.Mote2MoteRelations\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.interfaces.MoteAttributes\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.mspmote.interfaces.MspClock\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.mspmote.interfaces.MspMoteID\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.mspmote.interfaces.MspButton\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.mspmote.interfaces.CC2520Radio\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.mspmote.interfaces.UsciA1Serial\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.mspmote.interfaces.MspLED\"},\n {name: \"moteinterface\", text: \"org.contikios.cooja.mspmote.interfaces.MspDebugOutput\"}\n ]\n ]});\n}\n// Disturber motetype configuration\nif(GROUPs.disturber.length > 0)\n{\n sim_array.push({name: \"motetype\", text: \"org.contikios.cooja.motes.DisturberMoteType\", children:\n [\n {name: \"identifier\", text: \"apptype1\"},\n {name: \"description\", text: \"Disturber Mote Type #apptype1\"}\n ]});\n}\n\nfor(var g in GROUPs)\n{\n // Sink and Source nodes mote configuration\n if(g === \"sink\" || g === \"source\")\n {\n for(var n in GROUPs[g])\n {\n sim_array.push({name: \"mote\", children:\n [\n {name: \"breakpoints\"},\n {name: \"interface_config\", text: \"org.contikios.cooja.interfaces.Position\", children:\n [\n {name: \"x\", text: GROUPs[g][n].loc.X},\n {name: \"y\", text: GROUPs[g][n].loc.Y},\n {name: \"z\", text: \"0\"}\n ]},\n {name: \"interface_config\", text: \"org.contikios.cooja.mspmote.interfaces.MspClock\", children: [{name: \"deviation\", text: \"1.0\"}]},\n {name: \"interface_config\", text: \"org.contikios.cooja.mspmote.interfaces.MspMoteID\", children: [{name: \"id\", text: GROUPs[g][n].ID}]},\n {name: \"motetype_identifier\", text: platform + \"1\"}\n ]});\n }\n }\n // Disturber nodes mote configuration\n else if(g === \"disturber\")\n {\n for(var n in GROUPs[g])\n {\n sim_array.push({name: \"mote\", children:\n [\n {name: \"interface_config\", text: \"org.contikios.cooja.interfaces.Position\", children:\n [\n {name: \"x\", text: GROUPs[g][n].loc.X},\n {name: \"y\", text: GROUPs[g][n].loc.Y},\n {name: \"z\", text: \"0\"}\n ]},\n {name: \"interface_config\", text: \"org.contikios.cooja.motes.AbstractApplicationMoteType$SimpleMoteID\", children: [{name: \"id\", text: GROUPs[g][n].ID}]},\n {name: \"motetype_identifier\", text: \"apptype1\"}\n ]});\n }\n }\n}\n\n// Plugin configuration section\n// Simulation Timer plugin configuration\nsimconf.push({name: \"plugin\", text: \"org.contikios.cooja.plugins.simTimer\"});\n\n// Serial2Pty plugin configuration\nsimconf.push({name: \"plugin\", text: \"de.fau.cooja.plugins.Serial2PtyPlugin\"});\n\n// Script Runner plugin configuration\nsimconf.push({name: \"plugin\", text: \"org.contikios.cooja.plugins.ScriptRunner\", children:\n[\n {name: \"plugin_config\", children: \n [\n {name: \"script\", text: \"\\/\\/ Nashorn compatibility module for using importPackage within java 8\\nload(\\\"nashorn:mozilla_compat.js\\\");\\n\\/\\/import Java Package to JavaScript\\nimportPackage(java.io);\\n\\/\\/ file writer object\\nvar logWriter = new FileWriter(\\\"\" + contiki_log + context.global.RC_ID + \"\\\");\\n\\/\\/ Wait very long\\nTIMEOUT(1000000000000);\\nwhile (true){\\n\\tlogWriter.write(time + \\\" \\\" + id + \\\" \\\" + msg + \\\"\\\\n\\\");\\n\\tlogWriter.flush();\\n\\tYIELD();\\n}\"},\n {name: \"active\", text: \"true\"}\n ]}]\n});\n\n// Extra configuration for gui simulation mode\nif(simulation_mode === \"gui\")\n{\n // Event Listener plugin configuration\n simconf.push({name: \"plugin\", text: \"org.contikios.cooja.plugins.EventListener\"});\n \n // Power Tracker plugin configuration\n simconf.push({name: \"plugin\", text: \"PowerTracker\"});\n \n // Log listener plugin configuration\n simconf.push({name: \"plugin\", text: \"org.contikios.cooja.plugins.LogListener\"});\n \n // simulation control plugin configuration\n simconf.push({name: \"plugin\", text: \"org.contikios.cooja.plugins.SimControl\"});\n \n // Visualizer plugin configuration\n simconf.push({name: \"plugin\", text: \"org.contikios.cooja.plugins.Visualizer\", children:\n [\n {name: \"plugin_config\", children:\n [\n {name: \"skin\", text: \"org.contikios.cooja.plugins.skins.IDVisualizerSkin\"},\n {name: \"skin\", text: \"org.contikios.cooja.plugins.skins.GridVisualizerSkin\"},\n {name: \"skin\", text: \"org.contikios.cooja.plugins.skins.TrafficVisualizerSkin\"},\n {name: \"skin\", text: \"org.contikios.cooja.plugins.skins.UDGMVisualizerSkin\"},\n ]}\n ]});\n \n // Timeline plugin configuration\n var motecount = 0;\n var plugin_config = [];\n for(var g in GROUPs)\n {\n for(var n in GROUPs[g])\n {\n plugin_config.push({name: \"mote\", text: motecount});\n motecount++;\n }\n }\n plugin_config.push({name: \"showRadioRXTX\"});\n plugin_config.push({name: \"showRadioHW\"});\n simconf.push({name: \"plugin\", text: \"org.contikios.cooja.plugins.TimeLine\", children:\n [\n {name: \"plugin_config\", children: plugin_config}\n ]});\n}\n\nmsg.payload = {simconf: simconf};\n\nvar csc_path_rel = dirName(firm_path_rel) + \"/\" + baseName(firm_path_rel) + \".csc\";\nmsg.filename = CONTIKI_DIR + \"/\" + csc_path_rel;\n\nvar cooja = {};\ncooja.contiki_log = contiki_log;\ncooja.contiki_done_str = contiki_done_str;\ncooja.simulation_mode = simulation_mode;\ncooja.motetype = {};\ncooja.motetype.CONTIKI_DIR = CONTIKI_DIR;\ncooja.motetype.csc_path_rel = csc_path_rel;\nmsg.cooja = cooja;\n\nreturn msg;\n","outputs":1,"noerr":0,"x":210,"y":100,"wires":[["8144ebdf.376978"]]},{"id":"90a114f8.3fc108","type":"comment","z":"bf1a2f25.59371","name":"Create cooja simulation file","info":"","x":150,"y":60,"wires":[]},{"id":"b9705e75.dcab3","type":"exec","z":"bf1a2f25.59371","command":"pts_mux -g","addpay":true,"append":"","useSpawn":"true","timer":"","oldrc":true,"name":"start pts_mux","x":520,"y":400,"wires":[["64ac6270.65c05c"],["cb65a652.8b0178"],[]]},{"id":"64ac6270.65c05c","type":"function","z":"bf1a2f25.59371","name":"pts to nodeID","func":"\nif(msg.payload.indexOf(\"pts_mux has STARTED on port \") !== -1)\n{\n context.pts_mux_port = msg.payload.split(\" \")[5];\n context.pts_mux_PID = msg.payload.split(\" \")[8];\n}\nelse\n{\n context.ptyFiles_IDs = msg.payload;\n}\n\nif(typeof context.pts_mux_port !== 'undefined' && typeof context.pts_mux_PID !== 'undefined' && typeof context.ptyFiles_IDs !== 'undefined')\n//if(typeof context.ptyFiles_IDs !== 'undefined')\n{\n var ptyFiles_IDs = context.ptyFiles_IDs;\n var moteIDs = {};\n var GROUPs = context.global.GROUPs;\n \n // Make sure the number of assigned and configured pts devices are the same\n var pts_count = ptyFiles_IDs.length;\n var sink_count = GROUPs.sink.length;\n var source_count = GROUPs.source.length;\n var disturber_count = GROUPs.disturber.length;\n if(pts_count != sink_count + source_count + disturber_count)\n {\n msg.error = \"Assigned and configured nodes count does not match\";\n delete msg.payload;\n return [null, msg];\n }\n\n // Match [sink,source,disturber] nodes to pts devices\n\touter_loop:\n for(var i = 0; i < ptyFiles_IDs.length; i++)\n {\n var moteID = parseInt(ptyFiles_IDs[i].split('\\t')[0]);\n var ptyFile = ptyFiles_IDs[i].split('\\t')[1];\n moteIDs[ptyFile] = moteID;\n\n // Search mote ID within sink nodes\n for(var j = 0; j < sink_count; j++)\n {\n if(GROUPs.sink[j].ID === moteID)\n {\n GROUPs.sink[j].ptsFile = ptyFile;\n continue outer_loop;\n }\n }\n // Search mote ID within source nodes\n for(var k = 0; k < source_count; k++)\n {\n if(GROUPs.source[k].ID === moteID)\n {\n GROUPs.source[k].ptsFile = ptyFile;\n continue outer_loop;\n }\n }\n // Search mote ID within disturber nodes\n for(var l = 0; l < disturber_count; l++)\n {\n if(GROUPs.disturber[l].ID === moteID)\n {\n GROUPs.disturber[l].ptsFile = ptyFile;\n continue outer_loop;\n }\n }\n \n msg.error = \"simulated ptsFile = \" + ptyFile + \" is not part of configured nodes\";\n delete msg.payload;\n return [null, msg];\n }\n \n context.global.GROUPs = GROUPs;\n context.global.pts_mux_port = context.pts_mux_port;\n context.global.pts_mux_PID = context.pts_mux_PID;\n context.global.moteIDs = moteIDs;\n \n delete context.pts_mux_port;\n delete context.pts_mux_PID;\n delete context.ptyFiles_IDs;\n \n return [{topic: \"start_experiment\"}, {payload: \"Cooja is started on RC\" + context.global.RC_ID}];\n}","outputs":"2","noerr":0,"x":710,"y":380,"wires":[[],["3cec2cfe.3e89f4"]]},{"id":"709f977a.29a6c8","type":"link in","z":"bf1a2f25.59371","name":"pts_devices","links":["2b5e2c3e.0754d4"],"x":575,"y":340,"wires":[["64ac6270.65c05c"]]},{"id":"2b5e2c3e.0754d4","type":"link out","z":"bf1a2f25.59371","name":"pts_devices","links":["709f977a.29a6c8"],"x":455,"y":340,"wires":[]},{"id":"9d38e4b7.92b928","type":"tcpClient","z":"bf1a2f25.59371","name":"pts devices","host":"127.0.0.1","port":"6100","timeout":"10000","client_disconnects":false,"x":190,"y":400,"wires":[["751c0d1d.8e48d4"],["151eb726.2b9b89"]]},{"id":"8144ebdf.376978","type":"js2xml","z":"bf1a2f25.59371","name":"","x":390,"y":100,"wires":[["a065af16.05f5a"]]},{"id":"f11927e4.f8eeb8","type":"cooja","z":"bf1a2f25.59371","name":"cooja","restart_cooja":true,"debug":false,"x":310,"y":240,"wires":[["6db3b3bb.3b9c9c"],["2c1f121.67e65ee"]]},{"id":"2c1f121.67e65ee","type":"link out","z":"bf1a2f25.59371","name":"stderr","links":["fa960009.5778a"],"x":415,"y":260,"wires":[]},{"id":"6c8822.52c027e","type":"link in","z":"bf1a2f25.59371","name":"from_cooja","links":["896626e5.8671d8"],"x":55,"y":400,"wires":[["9d38e4b7.92b928"]]},{"id":"fa960009.5778a","type":"link in","z":"bf1a2f25.59371","name":"stderr","links":["2c1f121.67e65ee","151eb726.2b9b89","2edc926e.29303e","cb65a652.8b0178"],"x":755,"y":440,"wires":[["3cec2cfe.3e89f4"]]},{"id":"a7d1fcb0.51319","type":"comment","z":"bf1a2f25.59371","name":"(Re)Start cooja simulator","info":"","x":150,"y":200,"wires":[]},{"id":"101ba14e.025ebf","type":"link in","z":"bf1a2f25.59371","name":"to_cooja","links":["2a85a5b4.34ec4a"],"x":55,"y":240,"wires":[["3cae3ab9.fd9ed6"]]},{"id":"2a85a5b4.34ec4a","type":"link out","z":"bf1a2f25.59371","name":"to_cooja","links":["101ba14e.025ebf"],"x":655,"y":100,"wires":[]},{"id":"896626e5.8671d8","type":"link out","z":"bf1a2f25.59371","name":"from_cooja","links":["6c8822.52c027e"],"x":555,"y":220,"wires":[]},{"id":"1df7008b.23ff8f","type":"comment","z":"bf1a2f25.59371","name":"Start pts multiplexer","info":"","x":530,"y":300,"wires":[]},{"id":"3cae3ab9.fd9ed6","type":"function","z":"bf1a2f25.59371","name":"format","func":"\nvar cooja = msg.payload[0].cooja;\nvar topic = msg.payload[0].topic;\nvar CONTIKI_DIR = cooja.motetype.CONTIKI_DIR;\nvar csc_path_rel = cooja.motetype.csc_path_rel;\nvar simulation_mode = cooja.simulation_mode;\nvar contiki_log = cooja.contiki_log + context.global.RC_ID;\nvar contiki_done_str = cooja.contiki_done_str;\n\n// Sink and source nodes array\nvar GROUPs = context.global.GROUPs;\nvar node_IDs = [];\nfor(var i=0; i<GROUPs.sink.length; i++)\n node_IDs.push( GROUPs.sink[i].ID);\nfor(var i=0; i<GROUPs.source.length; i++)\n node_IDs.push( GROUPs.source[i].ID);\n\nreturn {CONTIKI_DIR: CONTIKI_DIR, csc_path_rel: csc_path_rel, simulation_mode: simulation_mode, contiki_log: contiki_log, contiki_done_str: contiki_done_str, node_IDs: node_IDs, topic: topic};\n","outputs":1,"noerr":0,"x":170,"y":240,"wires":[["f11927e4.f8eeb8"]]},{"id":"a065af16.05f5a","type":"Mfile_out","z":"bf1a2f25.59371","name":"cooja csc","appendNewline":true,"overwriteFile":"true","x":540,"y":100,"wires":[["2a85a5b4.34ec4a"]]},{"id":"151eb726.2b9b89","type":"link out","z":"bf1a2f25.59371","name":"stderr","links":["fa960009.5778a"],"x":315,"y":460,"wires":[]},{"id":"2edc926e.29303e","type":"link out","z":"bf1a2f25.59371","name":"stderr","links":["fa960009.5778a"],"x":455,"y":460,"wires":[]},{"id":"cb65a652.8b0178","type":"link out","z":"bf1a2f25.59371","name":"stderr","links":["fa960009.5778a"],"x":655,"y":440,"wires":[]},{"id":"6db3b3bb.3b9c9c","type":"function","z":"bf1a2f25.59371","name":"parser","func":"\nvar filePath = msg.CONTIKI_DIR + \"/\" + msg.csc_path_rel;\n\n// Make cooja pid a global variable\nif(typeof(msg.cooja_pid) !== \"undefined\")\n{\n context.global.cooja_pid = msg.cooja_pid;\n delete msg.cooja_pid;\n}\n\n// Make simTimer port a global variable\nif(typeof(msg.simTimer_port) !== \"undefined\")\n{\n context.global.simTimer_port = msg.simTimer_port;\n delete msg.simTimer_port;\n}\n\n// Rename serial2pty_port to port\nif(typeof(msg.serial2pty_port) !== \"undefined\")\n{\n msg.port = msg.serial2pty_port;\n delete msg.serial2pty_port;\n}\n\ndelete msg.CONTIKI_DIR;\ndelete msg.csc_path_rel;\ndelete msg.simulation_mode;\ndelete msg.contiki_log;\ndelete msg.node_IDs;\n\nmsg.payload = \"\";\nreturn msg;","outputs":1,"noerr":0,"x":450,"y":220,"wires":[["896626e5.8671d8"]]},{"id":"3cec2cfe.3e89f4","type":"debug","z":"bf1a2f25.59371","name":"stderr","active":true,"console":"false","complete":"true","x":870,"y":440,"wires":[]},{"id":"ca5b04e9.7dd678","type":"link out","z":"dfca7471.a1e698","name":"collection","links":["5f39396e.667518","5f4a2077.c42f2"],"x":775,"y":440,"wires":[]},{"id":"57ec8d9.f294274","type":"comment","z":"dfca7471.a1e698","name":"Environment","info":"","x":390,"y":240,"wires":[]},{"id":"224cdeb4.09de02","type":"subflow:bf1a2f25.59371","z":"dfca7471.a1e698","name":"","x":390,"y":280,"wires":[["d490cced.0bfc","f995d8d8.0d4328","9264f556.824c38"]]},{"id":"674284a2.87ec6c","type":"comment","z":"dfca7471.a1e698","name":"Start experiment","info":"","x":120,"y":40,"wires":[]},{"id":"8821dfb2.44752","type":"comment","z":"dfca7471.a1e698","name":"Stop experiment","info":"","x":580,"y":40,"wires":[]},{"id":"7129f714.4f1038","type":"inject","z":"dfca7471.a1e698","name":"Stop","topic":"stop_experiment","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"x":570,"y":80,"wires":[["dd983740.6ebbe8"]]},{"id":"dd983740.6ebbe8","type":"exec","z":"dfca7471.a1e698","command":"killall java ; killall pts_mux","addpay":false,"append":"","useSpawn":"","timer":"","oldrc":true,"name":"Stop APPs","x":730,"y":80,"wires":[[],["c1740649.64a018"],[]]},{"id":"c1740649.64a018","type":"link out","z":"dfca7471.a1e698","name":"stop_error","links":["5f4a2077.c42f2"],"x":855,"y":80,"wires":[]},{"id":"c10eea79.85a57","type":"LA","z":"dfca7471.a1e698","name":"LA-design","x":300,"y":520,"wires":[["1c66ecc.ac53013"],["dddd50c4.346e9"]]},{"id":"77e261e.1fa302","type":"BFS","z":"dfca7471.a1e698","outCol_Idx":"0","performLog":false,"nTerms":"10","nModels":"30","nNewModels":"30","response_path":"/root/samplesValues.txt","analysis_path":"/root/BFS_analysis.txt","name":"BFS-Analysis","x":830,"y":520,"wires":[["f666e010.4f7c1"],["570f448.32383bc"],["eedfe88b.bb6c28"]]},{"id":"f6d3eb40.3d072","type":"file in","z":"9e87c9ce.0ab558","name":"BFS analysis","filename":"","format":"utf8","x":290,"y":160,"wires":[["435cb67f.2559c8"]]},{"id":"435cb67f.2559c8","type":"function","z":"9e87c9ce.0ab558","name":"Occurrences","func":"\nvar payload = msg.payload;\nvar analysis_str = payload.substr(payload.indexOf(\"Final Models Ranking\"));\nvar analysis_array = analysis_str.split(\"\\n\");\n\n// Only select main effect and 2nd order interactions\nvar main_effects = {};\nvar interactions = {};\nfor(var i = 0; i < analysis_array.length; i++)\n{\n var line = analysis_array[i];\n \n var match_line = line.match(/=/gi);\n if(match_line !== null && match_line.length == 1)\n {\n var par = line.split(\"|\")[1].split(\"=\")[0].trim();\n if(typeof main_effects[par] === \"undefined\")\n main_effects[par] = 1;\n else\n main_effects[par] = main_effects[par] + 1;\n }\n else if(match_line !== null && match_line.length == 2)\n {\n var par1 = line.split(\"|\")[1].split(\"=\")[0].trim();\n var par2 = line.split(\"&\")[1].split(\"=\")[0].trim();\n if(typeof interactions[par1 + \" x \" + par2] === \"undefined\")\n interactions[par1 + \" x \" + par2] = 1;\n else\n interactions[par1 + \" x \" + par2] = interactions[par1 + \" x \" + par2] + 1;\n }\n}\n\ndelete msg.payload;\nmsg.occurrences = {main_effects: main_effects, interactions: interactions};\n\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":160,"wires":[["1e47311c.96e34f"]]}]