-
Notifications
You must be signed in to change notification settings - Fork 1
/
Discovery_Flow.json
1 lines (1 loc) · 30 KB
/
Discovery_Flow.json
1
[{"id":"be6ea61d.3a8f98","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"1435e921.b62767","type":"inject","z":"be6ea61d.3a8f98","name":"Trigger Auto Discovery","topic":"","payload":"{\"to\":\"node1\",\"from\":\"trigger\",\"data\":{\"action\":\"start_discovery\"}}","payloadType":"json","repeat":"2","crontab":"","once":true,"onceDelay":0.1,"x":530,"y":100,"wires":[["60527394.b2808c","dcfb3221.7b03c","7ecb9437.81981c","ee2674f.4b4a388","eae821fd.30e2","e11b5978.3d5a88"]]},{"id":"60527394.b2808c","type":"function","z":"be6ea61d.3a8f98","name":"Node 1","func":"context.set('id', 'node1');\nlet eResId = 'eRes' + context.get('id');\nflow.set(eResId, flow.get(eResId)*0.9999 );\n\nfunction getInitDiscoveryPayload() {\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'INIT_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction getInitDiscoveryACKPayload(to) {\n return {\n from: context.get('id'),\n to: to,\n data: {\n type: 'ACK_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction updateNeighborTable(payload) {\n var neighborTable = flow.get(context.get('id')) || {};\n neighborTable[payload.from] = {\n eRes: payload.data.eRes,\n sinkHops: payload.data.sinkHops\n };\n\n flow.set(context.get('id'), neighborTable);\n}\n\nfunction updateCurrentMinHop(newHops){\n var currentHop = context.get('sinkHops');\n var isUpdated = false;\n if(currentHop === -1){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }else if(newHops < currentHop){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }\n return isUpdated;\n}\n\nfunction getUpdateDistancePayload(){\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'UPDATE_DISTANCE',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\nfunction calculateCost(eRes,sinkHop) {\n let cost = (0.5*(100-eRes)/100) + (0.5*sinkHop/10);\n return cost;\n};\n\nfunction getNextHopId(){\n var neighborTable = flow.get(context.get('id'));\n\n var sortedNeighbors = Object.entries(neighborTable).sort((object1, object2) => calculateCost(object1[1].eRes , object1[1].sinkHops) - calculateCost(object2[1].eRes , object2[1].sinkHops))\n\n\n return sortedNeighbors[0][0];\n}\n\nfunction getForwardPayload(payload){\n return {\n from: payload.from,\n dest: payload.dest,\n to: getNextHopId(),\n path: payload.path.concat(context.get('id')),\n data: payload.data\n }\n}\n\n\nfunction computeCostAndDrainBattery() {\n flow.set(eResId, flow.get(eResId)*0.9999 );\n}\n\nfunction getDataPayload(){\n return {\n from: context.get('id'),\n dest: 'sink',\n to: getNextHopId(),\n path: [context.get('id')],\n data: {\n type: \"FORWARD_PAYLOAD\",\n value: 1\n }\n }\n}\n\nvar payload = {};\n\nif (msg.payload.from === context.get('id')) {\n payload = {};\n} else if (msg.payload.data.action === 'start_discovery') {\n payload = getInitDiscoveryPayload();\n context.set('sinkHops', -1);\n} else if (msg.payload.data.type === 'INIT_DISCOVERY' && msg.payload.from !== context.get('id')) {\n updateNeighborTable(msg.payload)\n payload = getInitDiscoveryACKPayload(msg.payload.from);\n} else if (msg.payload.data.type === 'ACK_DISCOVERY') {\n updateNeighborTable(msg.payload);\n\n if(msg.payload.data.isSink){\n var isUpdated = updateCurrentMinHop(1);\n if(isUpdated){\n payload = getUpdateDistancePayload();\n }\n }\n} else if(msg.payload.data.type === 'UPDATE_DISTANCE'){\n updateNeighborTable(msg.payload);\n var isUpdated = updateCurrentMinHop(msg.payload.data.sinkHops + 1);\n if (isUpdated){\n payload = getUpdateDistancePayload();\n }\n}\nelse if(msg.payload.data.type === 'FORWARD_PAYLOAD'){\n payload = getForwardPayload(msg.payload);\n computeCostAndDrainBattery();\n\n}\nelse if(msg.payload.data.type === 'ACTION_GENERATE_PAYLOAD'){\n payload = getDataPayload();\n}\n\nreturn {\n payload\n};","outputs":1,"noerr":0,"x":920,"y":200,"wires":[["75e00e03.997d2"]]},{"id":"75e00e03.997d2","type":"mqtt out","z":"be6ea61d.3a8f98","name":"Channel1 Out","topic":"channel1","qos":"","retain":"","broker":"3638882b.9415b8","x":1300,"y":260,"wires":[]},{"id":"b9b0a558.4bf368","type":"mqtt in","z":"be6ea61d.3a8f98","name":"Channel1 In","topic":"channel1","qos":"2","datatype":"auto","broker":"3638882b.9415b8","x":150,"y":220,"wires":[["4007c3ad.b5fc9c","e9c8e66b.435368"]]},{"id":"dcfb3221.7b03c","type":"function","z":"be6ea61d.3a8f98","name":"Node 2","func":"context.set('id', 'node2');\nlet eResId = 'eRes' + context.get('id');\nflow.set(eResId, flow.get(eResId)*0.9999 );\n\nfunction getInitDiscoveryPayload() {\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'INIT_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction getInitDiscoveryACKPayload(to) {\n return {\n from: context.get('id'),\n to: to,\n data: {\n type: 'ACK_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction updateNeighborTable(payload) {\n var neighborTable = flow.get(context.get('id')) || {};\n neighborTable[payload.from] = {\n eRes: payload.data.eRes,\n sinkHops: payload.data.sinkHops\n };\n\n flow.set(context.get('id'), neighborTable);\n}\n\nfunction updateCurrentMinHop(newHops){\n var currentHop = context.get('sinkHops');\n var isUpdated = false;\n if(currentHop === -1){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }else if(newHops < currentHop){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }\n return isUpdated;\n}\n\nfunction getUpdateDistancePayload(){\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'UPDATE_DISTANCE',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\nfunction calculateCost(eRes,sinkHop) {\n let cost = (0.5*(100-eRes)/100) + (0.5*sinkHop/10);\n return cost;\n};\n\nfunction getNextHopId(){\n var neighborTable = flow.get(context.get('id'));\n\n var sortedNeighbors = Object.entries(neighborTable).sort((object1, object2) => calculateCost(object1[1].eRes , object1[1].sinkHops) - calculateCost(object2[1].eRes , object2[1].sinkHops))\n\n\n return sortedNeighbors[0][0];\n}\n\nfunction getForwardPayload(payload){\n return {\n from: payload.from,\n dest: payload.dest,\n to: getNextHopId(),\n path: payload.path.concat(context.get('id')),\n data: payload.data\n }\n}\n\n\nfunction computeCostAndDrainBattery() {\n flow.set(eResId, flow.get(eResId)*0.9999 );\n}\n\nfunction getDataPayload(){\n return {\n from: context.get('id'),\n dest: 'sink',\n to: getNextHopId(),\n path: [context.get('id')],\n data: {\n type: \"FORWARD_PAYLOAD\",\n value: 1\n }\n }\n}\n\nvar payload = {};\n\nif (msg.payload.from === context.get('id')) {\n payload = {};\n} else if (msg.payload.data.action === 'start_discovery') {\n payload = getInitDiscoveryPayload();\n context.set('sinkHops', -1);\n} else if (msg.payload.data.type === 'INIT_DISCOVERY' && msg.payload.from !== context.get('id')) {\n updateNeighborTable(msg.payload)\n payload = getInitDiscoveryACKPayload(msg.payload.from);\n} else if (msg.payload.data.type === 'ACK_DISCOVERY') {\n updateNeighborTable(msg.payload);\n\n if(msg.payload.data.isSink){\n var isUpdated = updateCurrentMinHop(1);\n if(isUpdated){\n payload = getUpdateDistancePayload();\n }\n }\n} else if(msg.payload.data.type === 'UPDATE_DISTANCE'){\n updateNeighborTable(msg.payload);\n var isUpdated = updateCurrentMinHop(msg.payload.data.sinkHops + 1);\n if (isUpdated){\n payload = getUpdateDistancePayload();\n }\n}\nelse if(msg.payload.data.type === 'FORWARD_PAYLOAD'){\n payload = getForwardPayload(msg.payload);\n computeCostAndDrainBattery();\n\n}\nelse if(msg.payload.data.type === 'ACTION_GENERATE_PAYLOAD'){\n payload = getDataPayload();\n}\n\nreturn {\n payload\n};","outputs":1,"noerr":0,"x":920,"y":260,"wires":[["75e00e03.997d2","822f8aca.88c168"]]},{"id":"7ecb9437.81981c","type":"function","z":"be6ea61d.3a8f98","name":"Node 3","func":"context.set('id', 'node3');\nlet eResId = 'eRes' + context.get('id');\nflow.set(eResId, flow.get(eResId)*0.9999 );\n\nfunction getInitDiscoveryPayload() {\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'INIT_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction getInitDiscoveryACKPayload(to) {\n return {\n from: context.get('id'),\n to: to,\n data: {\n type: 'ACK_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction updateNeighborTable(payload) {\n var neighborTable = flow.get(context.get('id')) || {};\n neighborTable[payload.from] = {\n eRes: payload.data.eRes,\n sinkHops: payload.data.sinkHops\n };\n\n flow.set(context.get('id'), neighborTable);\n}\n\nfunction updateCurrentMinHop(newHops){\n var currentHop = context.get('sinkHops');\n var isUpdated = false;\n if(currentHop === -1){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }else if(newHops < currentHop){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }\n return isUpdated;\n}\n\nfunction getUpdateDistancePayload(){\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'UPDATE_DISTANCE',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\nfunction calculateCost(eRes,sinkHop) {\n let cost = (0.5*(100-eRes)/100) + (0.5*sinkHop/10);\n return cost;\n};\n\nfunction getNextHopId(){\n var neighborTable = flow.get(context.get('id'));\n\n var sortedNeighbors = Object.entries(neighborTable).sort((object1, object2) => calculateCost(object1[1].eRes , object1[1].sinkHops) - calculateCost(object2[1].eRes , object2[1].sinkHops))\n\n\n return sortedNeighbors[0][0];\n}\n\nfunction getForwardPayload(payload){\n return {\n from: payload.from,\n dest: payload.dest,\n to: getNextHopId(),\n path: payload.path.concat(context.get('id')),\n data: payload.data\n }\n}\n\n\nfunction computeCostAndDrainBattery() {\n flow.set(eResId, flow.get(eResId)*0.9999 );\n}\n\nfunction getDataPayload(){\n return {\n from: context.get('id'),\n dest: 'sink',\n to: getNextHopId(),\n path: [context.get('id')],\n data: {\n type: \"FORWARD_PAYLOAD\",\n value: 1\n }\n }\n}\n\nvar payload = {};\n\nif (msg.payload.from === context.get('id')) {\n payload = {};\n} else if (msg.payload.data.action === 'start_discovery') {\n payload = getInitDiscoveryPayload();\n context.set('sinkHops', -1);\n} else if (msg.payload.data.type === 'INIT_DISCOVERY' && msg.payload.from !== context.get('id')) {\n updateNeighborTable(msg.payload)\n payload = getInitDiscoveryACKPayload(msg.payload.from);\n} else if (msg.payload.data.type === 'ACK_DISCOVERY') {\n updateNeighborTable(msg.payload);\n\n if(msg.payload.data.isSink){\n var isUpdated = updateCurrentMinHop(1);\n if(isUpdated){\n payload = getUpdateDistancePayload();\n }\n }\n} else if(msg.payload.data.type === 'UPDATE_DISTANCE'){\n updateNeighborTable(msg.payload);\n var isUpdated = updateCurrentMinHop(msg.payload.data.sinkHops + 1);\n if (isUpdated){\n payload = getUpdateDistancePayload();\n }\n}\nelse if(msg.payload.data.type === 'FORWARD_PAYLOAD'){\n payload = getForwardPayload(msg.payload);\n computeCostAndDrainBattery();\n\n}\nelse if(msg.payload.data.type === 'ACTION_GENERATE_PAYLOAD'){\n payload = getDataPayload();\n}\n\nreturn {\n payload\n};","outputs":1,"noerr":0,"x":920,"y":320,"wires":[["75e00e03.997d2","822f8aca.88c168"]]},{"id":"a254f51.214b308","type":"debug","z":"be6ea61d.3a8f98","name":"Debug Channel 1","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":510,"y":300,"wires":[]},{"id":"9c59c5d1.d1efb8","type":"switch","z":"be6ea61d.3a8f98","name":"Network Router 1","property":"payload.to","propertyType":"msg","rules":[{"t":"eq","v":"node1","vt":"str"},{"t":"eq","v":"node2","vt":"str"},{"t":"eq","v":"node3","vt":"str"},{"t":"eq","v":"*","vt":"str"}],"checkall":"false","repair":false,"outputs":4,"x":510,"y":220,"wires":[["60527394.b2808c"],["dcfb3221.7b03c"],["7ecb9437.81981c"],["60527394.b2808c","dcfb3221.7b03c","7ecb9437.81981c"]]},{"id":"4007c3ad.b5fc9c","type":"json","z":"be6ea61d.3a8f98","name":"","property":"payload","action":"","pretty":false,"x":330,"y":220,"wires":[["9c59c5d1.d1efb8"]]},{"id":"e9c8e66b.435368","type":"json","z":"be6ea61d.3a8f98","name":"","property":"payload","action":"","pretty":false,"x":330,"y":300,"wires":[["a254f51.214b308"]]},{"id":"ee2674f.4b4a388","type":"function","z":"be6ea61d.3a8f98","name":"Node 4","func":"context.set('id', 'node4');\nlet eResId = 'eRes' + context.get('id');\nflow.set(eResId, flow.get(eResId)*0.9999 );\n\nfunction getInitDiscoveryPayload() {\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'INIT_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction getInitDiscoveryACKPayload(to) {\n return {\n from: context.get('id'),\n to: to,\n data: {\n type: 'ACK_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction updateNeighborTable(payload) {\n var neighborTable = flow.get(context.get('id')) || {};\n neighborTable[payload.from] = {\n eRes: payload.data.eRes,\n sinkHops: payload.data.sinkHops\n };\n\n flow.set(context.get('id'), neighborTable);\n}\n\nfunction updateCurrentMinHop(newHops){\n var currentHop = context.get('sinkHops');\n var isUpdated = false;\n if(currentHop === -1){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }else if(newHops < currentHop){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }\n return isUpdated;\n}\n\nfunction getUpdateDistancePayload(){\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'UPDATE_DISTANCE',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\nfunction calculateCost(eRes,sinkHop) {\n let cost = (0.5*(100-eRes)/100) + (0.5*sinkHop/10);\n return cost;\n};\n\nfunction getNextHopId(){\n var neighborTable = flow.get(context.get('id'));\n\n var sortedNeighbors = Object.entries(neighborTable).sort((object1, object2) => calculateCost(object1[1].eRes , object1[1].sinkHops) - calculateCost(object2[1].eRes , object2[1].sinkHops))\n\n\n return sortedNeighbors[0][0];\n}\n\nfunction getForwardPayload(payload){\n return {\n from: payload.from,\n dest: payload.dest,\n to: getNextHopId(),\n path: payload.path.concat(context.get('id')),\n data: payload.data\n }\n}\n\n\nfunction computeCostAndDrainBattery() {\n flow.set(eResId, flow.get(eResId)*0.9999 );\n}\n\nfunction getDataPayload(){\n return {\n from: context.get('id'),\n dest: 'sink',\n to: getNextHopId(),\n path: [context.get('id')],\n data: {\n type: \"FORWARD_PAYLOAD\",\n value: 1\n }\n }\n}\n\nvar payload = {};\n\nif (msg.payload.from === context.get('id')) {\n payload = {};\n} else if (msg.payload.data.action === 'start_discovery') {\n payload = getInitDiscoveryPayload();\n context.set('sinkHops', -1);\n} else if (msg.payload.data.type === 'INIT_DISCOVERY' && msg.payload.from !== context.get('id')) {\n updateNeighborTable(msg.payload)\n payload = getInitDiscoveryACKPayload(msg.payload.from);\n} else if (msg.payload.data.type === 'ACK_DISCOVERY') {\n updateNeighborTable(msg.payload);\n\n if(msg.payload.data.isSink){\n var isUpdated = updateCurrentMinHop(1);\n if(isUpdated){\n payload = getUpdateDistancePayload();\n }\n }\n} else if(msg.payload.data.type === 'UPDATE_DISTANCE'){\n updateNeighborTable(msg.payload);\n var isUpdated = updateCurrentMinHop(msg.payload.data.sinkHops + 1);\n if (isUpdated){\n payload = getUpdateDistancePayload();\n }\n}\nelse if(msg.payload.data.type === 'FORWARD_PAYLOAD'){\n payload = getForwardPayload(msg.payload);\n computeCostAndDrainBattery();\n\n}\nelse if(msg.payload.data.type === 'ACTION_GENERATE_PAYLOAD'){\n payload = getDataPayload();\n}\n\nreturn {\n payload\n};","outputs":1,"noerr":0,"x":920,"y":500,"wires":[["822f8aca.88c168","e814047f.166b08"]]},{"id":"822f8aca.88c168","type":"mqtt out","z":"be6ea61d.3a8f98","name":"Channel2 Out","topic":"channel2","qos":"","retain":"","broker":"3638882b.9415b8","x":1300,"y":500,"wires":[]},{"id":"964a4435.799598","type":"mqtt in","z":"be6ea61d.3a8f98","name":"Channel2 In","topic":"channel2","qos":"2","datatype":"auto","broker":"3638882b.9415b8","x":130,"y":520,"wires":[["6b64440e.59308c","36700907.a5b516"]]},{"id":"eae821fd.30e2","type":"function","z":"be6ea61d.3a8f98","name":"Node 5","func":"context.set('id', 'node5');\nlet eResId = 'eRes' + context.get('id');\nflow.set(eResId, flow.get(eResId)*0.9999 );\n\nfunction getInitDiscoveryPayload() {\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'INIT_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction getInitDiscoveryACKPayload(to) {\n return {\n from: context.get('id'),\n to: to,\n data: {\n type: 'ACK_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction updateNeighborTable(payload) {\n var neighborTable = flow.get(context.get('id')) || {};\n neighborTable[payload.from] = {\n eRes: payload.data.eRes,\n sinkHops: payload.data.sinkHops\n };\n\n flow.set(context.get('id'), neighborTable);\n}\n\nfunction updateCurrentMinHop(newHops){\n var currentHop = context.get('sinkHops');\n var isUpdated = false;\n if(currentHop === -1){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }else if(newHops < currentHop){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }\n return isUpdated;\n}\n\nfunction getUpdateDistancePayload(){\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'UPDATE_DISTANCE',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\nfunction calculateCost(eRes,sinkHop) {\n let cost = (0.5*(100-eRes)/100) + (0.5*sinkHop/10);\n return cost;\n};\n\nfunction getNextHopId(){\n var neighborTable = flow.get(context.get('id'));\n\n var sortedNeighbors = Object.entries(neighborTable).sort((object1, object2) => object1[1].sinkHops - object2[1].sinkHops)\n\n return sortedNeighbors[0][0];\n}\n\nfunction getForwardPayload(payload){\n return {\n from: payload.from,\n dest: payload.dest,\n to: getNextHopId(),\n path: payload.path.concat(context.get('id')),\n data: payload.data\n }\n}\n\n\nfunction computeCostAndDrainBattery() {\n flow.set(eResId, flow.get(eResId)*0.9999 );\n}\n\nfunction getDataPayload(){\n return {\n from: context.get('id'),\n dest: 'sink',\n to: getNextHopId(),\n path: [context.get('id')],\n data: {\n type: \"FORWARD_PAYLOAD\",\n value: 1\n }\n }\n}\n\nvar payload = {};\n\nif (msg.payload.from === context.get('id')) {\n payload = {};\n} else if (msg.payload.data.action === 'start_discovery') {\n payload = getInitDiscoveryPayload();\n context.set('sinkHops', -1);\n} else if (msg.payload.data.type === 'INIT_DISCOVERY' && msg.payload.from !== context.get('id')) {\n updateNeighborTable(msg.payload)\n payload = getInitDiscoveryACKPayload(msg.payload.from);\n} else if (msg.payload.data.type === 'ACK_DISCOVERY') {\n updateNeighborTable(msg.payload);\n\n if(msg.payload.data.isSink){\n var isUpdated = updateCurrentMinHop(1);\n if(isUpdated){\n payload = getUpdateDistancePayload();\n }\n }\n} else if(msg.payload.data.type === 'UPDATE_DISTANCE'){\n updateNeighborTable(msg.payload);\n var isUpdated = updateCurrentMinHop(msg.payload.data.sinkHops + 1);\n if (isUpdated){\n payload = getUpdateDistancePayload();\n }\n}\nelse if(msg.payload.data.type === 'FORWARD_PAYLOAD'){\n payload = getForwardPayload(msg.payload);\n computeCostAndDrainBattery();\n\n}\nelse if(msg.payload.data.type === 'ACTION_GENERATE_PAYLOAD'){\n payload = getDataPayload();\n}\n\nreturn {\n payload\n};","outputs":1,"noerr":0,"x":920,"y":560,"wires":[["822f8aca.88c168","e814047f.166b08"]]},{"id":"b3fc3d9f.08d03","type":"debug","z":"be6ea61d.3a8f98","name":"Debug Channel 2","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":530,"y":620,"wires":[]},{"id":"de7a050e.fdf188","type":"switch","z":"be6ea61d.3a8f98","name":"Network Router 2","property":"payload.to","propertyType":"msg","rules":[{"t":"eq","v":"node2","vt":"str"},{"t":"eq","v":"node3","vt":"str"},{"t":"eq","v":"node4","vt":"str"},{"t":"eq","v":"node5","vt":"str"},{"t":"eq","v":"*","vt":"str"}],"checkall":"false","repair":false,"outputs":5,"x":530,"y":520,"wires":[["dcfb3221.7b03c"],["7ecb9437.81981c"],["ee2674f.4b4a388"],["eae821fd.30e2"],["ee2674f.4b4a388","eae821fd.30e2","7ecb9437.81981c","dcfb3221.7b03c"]]},{"id":"6b64440e.59308c","type":"json","z":"be6ea61d.3a8f98","name":"","property":"payload","action":"","pretty":false,"x":330,"y":520,"wires":[["de7a050e.fdf188"]]},{"id":"36700907.a5b516","type":"json","z":"be6ea61d.3a8f98","name":"","property":"payload","action":"","pretty":false,"x":330,"y":620,"wires":[["b3fc3d9f.08d03"]]},{"id":"e11b5978.3d5a88","type":"function","z":"be6ea61d.3a8f98","name":"Sink","func":"context.set('id', 'node6');\nlet eResId = 'eRes' + context.get('id');\nflow.set(eResId, flow.get(eResId)*0.9999 );\n\nfunction getInitDiscoveryPayload() {\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'INIT_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\n\nfunction getInitDiscoveryACKPayload(to) {\n return {\n from: context.get('id'),\n to: to,\n data: {\n type: 'ACK_DISCOVERY',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops'),\n isSink: true\n }\n }\n}\n\nfunction updateNeighborTable(payload) {\n var neighborTable = flow.get(context.get('id')) || {};\n neighborTable[payload.from] = {\n eRes: payload.data.eRes,\n sinkHops: payload.data.sinkHops\n };\n\n flow.set(context.get('id'), neighborTable);\n}\n\nfunction updateCurrentMinHop(newHops){\n var currentHop = context.get('sinkHops');\n var isUpdated = false;\n if(currentHop === -1){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }else if(newHops < currentHop){\n isUpdated = true;\n context.set('sinkHops', newHops);\n }\n return isUpdated;\n}\n\nfunction getUpdateDistancePayload(){\n return {\n from: context.get('id'),\n to: '*',\n data: {\n type: 'UPDATE_DISTANCE',\n eRes: flow.get(eResId),\n sinkHops: context.get('sinkHops')\n }\n }\n}\nfunction calculateCost(eRes,sinkHop) {\n let cost = (0.5*(100-eRes)/100) + (0.5*sinkHop/10);\n return cost;\n};\n\nfunction getNextHopId(){\n var neighborTable = flow.get(context.get('id'));\n\n var sortedNeighbors = Object.entries(neighborTable).sort((object1, object2) => calculateCost(object1[1].eRes , object1[1].sinkHops) - calculateCost(object2[1].eRes , object2[1].sinkHops))\n\n\n return sortedNeighbors[0][0];\n}\n\nfunction getForwardPayload(payload){\n return {\n from: payload.from,\n dest: payload.dest,\n to: getNextHopId(),\n path: payload.path.concat(context.get('id')),\n data: payload.data\n }\n}\n\n\nfunction computeCostAndDrainBattery() {\n flow.set(eResId, flow.get(eResId)*0.9999);\n}\n\nfunction getDataPayload(){\n return {\n from: context.get('id'),\n dest: 'sink',\n to: getNextHopId(),\n path: [context.get('id')],\n data: {\n type: \"FORWARD_PAYLOAD\",\n value: 1\n }\n }\n}\n\nvar payload = {};\n\nif (msg.payload.from === context.get('id')) {\n payload = {};\n} else if (msg.payload.data.action === 'start_discovery') {\n payload = getInitDiscoveryPayload();\n context.set('sinkHops', 0);\n} else if (msg.payload.data.type === 'INIT_DISCOVERY' && msg.payload.from !== context.get('id')) {\n updateNeighborTable(msg.payload)\n payload = getInitDiscoveryACKPayload(msg.payload.from);\n} else if (msg.payload.data.type === 'ACK_DISCOVERY') {\n updateNeighborTable(msg.payload);\n\n if(msg.payload.data.isSink){\n var isUpdated = updateCurrentMinHop(1);\n if(isUpdated){\n payload = getUpdateDistancePayload();\n }\n }\n} else if(msg.payload.data.type === 'UPDATE_DISTANCE'){\n updateNeighborTable(msg.payload);\n var isUpdated = updateCurrentMinHop(msg.payload.data.sinkHops + 1);\n if (isUpdated){\n payload = getUpdateDistancePayload();\n }\n}\nelse if(msg.payload.data.type === 'FORWARD_PAYLOAD'){\n payload = getForwardPayload(msg.payload);\n computeCostAndDrainBattery();\n\n}\nelse if(msg.payload.data.type === 'ACTION_GENERATE_PAYLOAD'){\n payload = getDataPayload();\n}\n\nreturn {\n payload\n};","outputs":1,"noerr":0,"x":910,"y":740,"wires":[["e7689b8d.55f0d8"]]},{"id":"e814047f.166b08","type":"mqtt out","z":"be6ea61d.3a8f98","name":"Channel3 Out","topic":"channel3","qos":"","retain":"","broker":"3638882b.9415b8","x":1320,"y":720,"wires":[]},{"id":"46d8b2a0.68fd8c","type":"mqtt in","z":"be6ea61d.3a8f98","name":"Channel3 In","topic":"channel3","qos":"2","datatype":"auto","broker":"3638882b.9415b8","x":130,"y":740,"wires":[["6119744f.bcd65c","4c9d4f42.c1ba6"]]},{"id":"ca14c6c9.e639e8","type":"debug","z":"be6ea61d.3a8f98","name":"Debug Channel 3","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":530,"y":840,"wires":[]},{"id":"8c836601.122498","type":"switch","z":"be6ea61d.3a8f98","name":"Network Router 3","property":"payload.to","propertyType":"msg","rules":[{"t":"eq","v":"node6","vt":"str"},{"t":"eq","v":"node4","vt":"str"},{"t":"eq","v":"node5","vt":"str"},{"t":"eq","v":"*","vt":"str"}],"checkall":"false","repair":false,"outputs":4,"x":530,"y":740,"wires":[["e11b5978.3d5a88"],["ee2674f.4b4a388"],["eae821fd.30e2"],["e11b5978.3d5a88","eae821fd.30e2","ee2674f.4b4a388"]]},{"id":"6119744f.bcd65c","type":"json","z":"be6ea61d.3a8f98","name":"","property":"payload","action":"","pretty":false,"x":330,"y":740,"wires":[["8c836601.122498"]]},{"id":"4c9d4f42.c1ba6","type":"json","z":"be6ea61d.3a8f98","name":"","property":"payload","action":"","pretty":false,"x":330,"y":840,"wires":[["ca14c6c9.e639e8"]]},{"id":"a8e0ef0b.20a4b","type":"function","z":"be6ea61d.3a8f98","name":"Initialize Battery","func":"\nflow.set('eResnode1', 100);\nflow.set('eResnode2', 100);\nflow.set('eResnode3', 100);\nflow.set('eResnode4', 100);\nflow.set('eResnode5', 100);\nflow.set('eResnode6', 100);\n\nreturn msg;","outputs":1,"noerr":0,"x":1440,"y":60,"wires":[[]]},{"id":"3f0bb1b7.adbc1e","type":"inject","z":"be6ea61d.3a8f98","name":"Init","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":1270,"y":60,"wires":[["a8e0ef0b.20a4b"]]},{"id":"e9404b1.1c799b8","type":"inject","z":"be6ea61d.3a8f98","name":"Trigger","topic":"","payload":"","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":"0.5","x":510,"y":40,"wires":[["e7953ff5.4a297"]]},{"id":"e7953ff5.4a297","type":"function","z":"be6ea61d.3a8f98","name":"Inject Sensor Data","func":"return {\n payload: {\n data: {\n type: 'ACTION_GENERATE_PAYLOAD'\n }\n }\n};","outputs":1,"noerr":0,"x":710,"y":40,"wires":[["60527394.b2808c"]]},{"id":"a7ff8e9e.55833","type":"debug","z":"be6ea61d.3a8f98","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1490,"y":800,"wires":[]},{"id":"81c8e383.c31d","type":"function","z":"be6ea61d.3a8f98","name":"Path Display","func":"let p = msg.payload.path.reduce((a,b) => {return a + \"==>\" + b});\nmsg.payload = {\n path: p,\n payload: msg.payload\n}\nreturn msg\n","outputs":1,"noerr":0,"x":1330,"y":800,"wires":[["a7ff8e9e.55833"]]},{"id":"e7689b8d.55f0d8","type":"switch","z":"be6ea61d.3a8f98","name":"","property":"payload.data.type","propertyType":"msg","rules":[{"t":"eq","v":"FORWARD_PAYLOAD","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":1090,"y":740,"wires":[["81c8e383.c31d"],["e814047f.166b08"]]},{"id":"3638882b.9415b8","type":"mqtt-broker","z":"","name":"Localhost","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]