Skip to content

Instantly share code, notes, and snippets.

@getlarge
Created November 13, 2019 19:51
Show Gist options
  • Save getlarge/9a141700c2724656141f8152e4cae0e9 to your computer and use it in GitHub Desktop.
Save getlarge/9a141700c2724656141f8152e4cae0e9 to your computer and use it in GitHub Desktop.
node-red-bridge-iota/device-flow
[
{
"id": "c8603d46.4fae9",
"type": "subflow",
"name": "check-service-balance",
"info": "",
"category": "iota",
"in": [
{
"x": 260,
"y": 140,
"wires": [
{
"id": "977dc013.d65778"
}
]
}
],
"out": [
{
"x": 700,
"y": 100,
"wires": [
{
"id": "977dc013.d65778",
"port": 0
}
]
},
{
"x": 700,
"y": 180,
"wires": [
{
"id": "977dc013.d65778",
"port": 1
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
},
{
"name": "device_id",
"type": "env",
"value": "device_id"
},
{
"name": "store_type",
"type": "str",
"value": "file"
}
],
"outputLabels": [
"success",
"failure"
]
},
{
"id": "977dc013.d65778",
"type": "function",
"z": "c8603d46.4fae9",
"name": "check-service-balance",
"func": "const checkServiceBalance = (msg, deviceId, storeType) => {\n try {\n let service;\n global.get(`service-${deviceId}`, storeType, (err, res) => {\n if (err) throw err;\n service = res || null; \n });\n if (!service || service === null) throw new Error(\"No service found\");\n\n if (service.currentBalance > 0.5) {\n if (msg.payload === true) {\n service.currentBalance -= 0.5; \n service.currentBalance = service.currentBalance.toFixed(4);\n console.log(\"PICTURE ON, BALANCE : \", service.currentBalance);\n global.set(`service-${deviceId}`, service, storeType, (err) => {\n if (err) throw err;\n });\n }\n return true;\n } \n return false;\n } catch(error) {\n return false;\n }\n}\n\ntry {\n const storeType = env.get('store_type');\n const deviceId = env.get('device_id');\n if (!deviceId || deviceId === null) throw new Error('Missing device id');\n\n if (checkServiceBalance(msg, deviceId, storeType)) {\n return [msg, null];\n }\n msg.payload = 'Not enough balance, reload device account in order to use it';\n return [null, msg]; \n} catch(error) {\n return error;\n}\n ",
"outputs": 2,
"noerr": 0,
"x": 440,
"y": 140,
"wires": [
[],
[]
]
},
{
"id": "4b46392d.a45d7",
"type": "subflow",
"name": "set-buffer",
"info": "",
"category": "function",
"in": [
{
"x": 180,
"y": 200,
"wires": [
{
"id": "57e39f2.e6d68e"
}
]
}
],
"out": [
{
"x": 460,
"y": 200,
"wires": [
{
"id": "57e39f2.e6d68e",
"port": 0
}
]
}
],
"env": [
{
"name": "resource_id",
"type": "str",
"value": ""
},
{
"name": "content_type",
"type": "str",
"value": ""
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"icon": "font-awesome/fa-check"
},
{
"id": "57e39f2.e6d68e",
"type": "function",
"z": "4b46392d.a45d7",
"name": "setBuffer",
"func": "try {\n const debug = env.get(\"debug\");\n if (!msg || msg === null || !msg.sensor) throw new Error(\"No input to parse\");\n const resourceId = env.get(\"resource_id\");\n if (!resourceId) throw new Error(\"no resource id set\");\n const value = msg.sensor.resources[resourceId];\n if (!value) throw new Error(\"no sensor value found\");\n if (debug) {\n console.log(`get-buffer for ${resourceId}`, typeof value);\n }\n if (typeof value === \"string\") {\n if ( value === \"1\" || value === \"true\") return null;\n else if (value === \"false\" || value === \"0\") {\n msg.reset = true;\n return msg;\n } \n if (JSON.parse(value)) {\n msg.payload = JSON.parse(value).data;\n } else {\n msg.payload = Buffer.from(value, 'utf-8').toJSON().data; \n } \n // msg.payload = Buffer.from(value, 'utf-8').toJSON(); \n } else if (typeof value === \"object\" && value.type && value.data){\n msg.payload = value.data;\n } else if (Buffer.isBuffer(value)){\n msg.payload = value;\n }\n const type = env.get(\"content_type\");\n if (type && type !== null) {\n msg.mimetype = type; \n }\n msg.payload = Buffer.from(msg.payload);\n if (debug) {\n console.log(`set-buffer for ${resourceId}`, Buffer.isBuffer(msg.payload));\n }\n return msg;\n} catch(error) {\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 320,
"y": 200,
"wires": [
[]
]
},
{
"id": "1be19fb.0ff37e",
"type": "subflow",
"name": "node-webcam-logic",
"info": "",
"category": "camera",
"in": [
{
"x": 100,
"y": 180,
"wires": [
{
"id": "9967a937.15417"
}
]
}
],
"out": [
{
"x": 980,
"y": 200,
"wires": [
{
"id": "99901dd2.ef26e",
"port": 0
}
]
},
{
"x": 1180,
"y": 500,
"wires": [
{
"id": "a6e0055d.8ecb68",
"port": 0
}
]
},
{
"x": 1180,
"y": 560,
"wires": [
{
"id": "20c87f24.69737",
"port": 0
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
},
{
"name": "device_id",
"type": "env",
"value": "device_id"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "store_type",
"type": "env",
"value": "store_type"
}
],
"outputLabels": [
"device-properties",
"3349/1/5910",
"3349/1/5911"
],
"icon": "node-red/batch.png"
},
{
"id": "e10208c2.b68398",
"type": "switch",
"z": "1be19fb.0ff37e",
"name": "3349-resourceId",
"property": "sensor.resource",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "5910",
"vt": "str"
},
{
"t": "eq",
"v": "5911",
"vt": "str"
},
{
"t": "eq",
"v": "5850",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 3,
"x": 670,
"y": 540,
"wires": [
[
"444474b9.b725bc"
],
[
"20c87f24.69737"
],
[]
]
},
{
"id": "ba6186cf.36f45",
"type": "switch",
"z": "1be19fb.0ff37e",
"name": "objectId",
"property": "sensor.type",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "3306",
"vt": "str"
},
{
"t": "eq",
"v": "3349",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 440,
"y": 540,
"wires": [
[],
[
"e10208c2.b68398"
]
]
},
{
"id": "444474b9.b725bc",
"type": "switch",
"z": "1be19fb.0ff37e",
"name": "5910-sensorId",
"property": "sensor.nativeSensorId",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "2",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 920,
"y": 500,
"wires": [
[
"a6e0055d.8ecb68"
]
]
},
{
"id": "20c87f24.69737",
"type": "switch",
"z": "1be19fb.0ff37e",
"name": "5911-sensorId",
"property": "sensor.nativeSensorId",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "2",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 920,
"y": 560,
"wires": [
[]
]
},
{
"id": "4b45b070.ea8d38",
"type": "debug",
"z": "1be19fb.0ff37e",
"name": "${device_name}",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 220,
"y": 280,
"wires": []
},
{
"id": "9967a937.15417",
"type": "subflow:744e75eb.cf669c",
"z": "1be19fb.0ff37e",
"name": "",
"env": [],
"x": 230,
"y": 180,
"wires": [
[
"7872c69d.6739c8"
],
[
"682cd1cf.050ff8"
],
[],
[],
[
"54327cf7.e8c9d4"
],
[
"4b45b070.ea8d38"
]
]
},
{
"id": "83523422.b65398",
"type": "link in",
"z": "1be19fb.0ff37e",
"name": "->filter-sensors",
"links": [
"682cd1cf.050ff8",
"d6bf35bb.154998"
],
"x": 95,
"y": 540,
"wires": [
[
"2697f654.c3af42"
]
]
},
{
"id": "682cd1cf.050ff8",
"type": "link out",
"z": "1be19fb.0ff37e",
"name": "filter-sensors->",
"links": [
"83523422.b65398"
],
"x": 435,
"y": 140,
"wires": []
},
{
"id": "d6bf35bb.154998",
"type": "link out",
"z": "1be19fb.0ff37e",
"name": "filter-sensors->",
"links": [
"83523422.b65398"
],
"x": 475,
"y": 1060,
"wires": []
},
{
"id": "671719c6.6185e8",
"type": "comment",
"z": "1be19fb.0ff37e",
"name": "Filter sensor properties",
"info": "",
"x": 180,
"y": 420,
"wires": []
},
{
"id": "712bdef9.3c0a88",
"type": "comment",
"z": "1be19fb.0ff37e",
"name": "FLOW INPUT",
"info": "",
"x": 150,
"y": 60,
"wires": []
},
{
"id": "e98ea1dc.7227e",
"type": "comment",
"z": "1be19fb.0ff37e",
"name": "Refresh interfaces",
"info": "",
"x": 170,
"y": 860,
"wires": []
},
{
"id": "fd4cad34.e5c428",
"type": "inject",
"z": "1be19fb.0ff37e",
"name": "refreshViews",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "60",
"crontab": "",
"once": true,
"onceDelay": "30",
"x": 160,
"y": 920,
"wires": [
[]
]
},
{
"id": "21987813.972d28",
"type": "subflow:8a55823f.f6ad1",
"z": "1be19fb.0ff37e",
"name": "get-sensor-3306-1",
"env": [
{
"name": "object_id",
"type": "str",
"value": "3306"
}
],
"x": 270,
"y": 1060,
"wires": [
[
"d6bf35bb.154998"
]
]
},
{
"id": "d235543d.58e8a8",
"type": "subflow:8a55823f.f6ad1",
"z": "1be19fb.0ff37e",
"name": "get-sensor-3349-2",
"env": [
{
"name": "object_id",
"type": "str",
"value": "3349"
},
{
"name": "sensor_id",
"type": "str",
"value": "2"
}
],
"x": 270,
"y": 1120,
"wires": [
[
"d6bf35bb.154998"
]
]
},
{
"id": "a6e0055d.8ecb68",
"type": "subflow:4b46392d.a45d7",
"z": "1be19fb.0ff37e",
"name": "",
"env": [
{
"name": "resource_id",
"type": "str",
"value": "5910"
},
{
"name": "content_type",
"type": "str",
"value": "jpg"
}
],
"x": 1080,
"y": 500,
"wires": [
[]
]
},
{
"id": "7872c69d.6739c8",
"type": "link out",
"z": "1be19fb.0ff37e",
"name": "filter-device->",
"links": [
"99901dd2.ef26e"
],
"x": 435,
"y": 100,
"wires": []
},
{
"id": "2412c4a7.3ad4f4",
"type": "comment",
"z": "1be19fb.0ff37e",
"name": "Filter triggers",
"info": "",
"x": 150,
"y": 680,
"wires": []
},
{
"id": "14f07dba.1f520a",
"type": "link in",
"z": "1be19fb.0ff37e",
"name": "->filter-triggers",
"links": [
"54327cf7.e8c9d4"
],
"x": 95,
"y": 760,
"wires": [
[
"8f8cdc4a.a911f"
]
]
},
{
"id": "8f8cdc4a.a911f",
"type": "switch",
"z": "1be19fb.0ff37e",
"name": "Command",
"property": "trigger",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "refresh",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 1,
"x": 510,
"y": 760,
"wires": [
[
"992e7376.2e92d8"
]
]
},
{
"id": "992e7376.2e92d8",
"type": "switch",
"z": "1be19fb.0ff37e",
"name": "Collection",
"property": "collection",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "sensor",
"vt": "str"
},
{
"t": "eq",
"v": "device",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 760,
"y": 760,
"wires": [
[
"2ef3d562.a5ee22"
],
[
"5aeb1791.bebb78"
]
]
},
{
"id": "2ef3d562.a5ee22",
"type": "link out",
"z": "1be19fb.0ff37e",
"name": "trigger-refresh-sensor->",
"links": [
"66d726d5.27ab5"
],
"x": 1015,
"y": 720,
"wires": []
},
{
"id": "5aeb1791.bebb78",
"type": "link out",
"z": "1be19fb.0ff37e",
"name": "trigger-refresh-device->",
"links": [
"dce338f8.ef6d"
],
"x": 1015,
"y": 800,
"wires": []
},
{
"id": "dce338f8.ef6d",
"type": "link in",
"z": "1be19fb.0ff37e",
"name": "->trigger-refresh-device",
"links": [
"5aeb1791.bebb78"
],
"x": 95,
"y": 1000,
"wires": [
[
"f3198fe7.9163e8"
]
]
},
{
"id": "49d2ad2a.b9744c",
"type": "link out",
"z": "1be19fb.0ff37e",
"name": "filter-device->",
"links": [
"99901dd2.ef26e"
],
"x": 480,
"y": 1000,
"wires": []
},
{
"id": "f3198fe7.9163e8",
"type": "subflow:d253d97e.e3e448",
"z": "1be19fb.0ff37e",
"name": "get-device-camera2",
"env": [],
"x": 280,
"y": 1000,
"wires": [
[
"49d2ad2a.b9744c"
]
]
},
{
"id": "54327cf7.e8c9d4",
"type": "link out",
"z": "1be19fb.0ff37e",
"name": "filter-triggers->",
"links": [
"14f07dba.1f520a"
],
"x": 435,
"y": 220,
"wires": []
},
{
"id": "66d726d5.27ab5",
"type": "link in",
"z": "1be19fb.0ff37e",
"name": "->trigger-refresh-sensors",
"links": [
"2ef3d562.a5ee22"
],
"x": 95,
"y": 1060,
"wires": [
[
"21987813.972d28",
"d235543d.58e8a8"
]
]
},
{
"id": "99901dd2.ef26e",
"type": "link in",
"z": "1be19fb.0ff37e",
"name": "device-output->",
"links": [
"7872c69d.6739c8",
"49d2ad2a.b9744c"
],
"x": 855,
"y": 200,
"wires": [
[]
]
},
{
"id": "2697f654.c3af42",
"type": "change",
"z": "1be19fb.0ff37e",
"name": "",
"rules": [
{
"t": "set",
"p": "method",
"pt": "msg",
"to": "parts[2]",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 240,
"y": 540,
"wires": [
[
"ba6186cf.36f45"
]
]
},
{
"id": "35404dde.e62b92",
"type": "subflow",
"name": "camera-2",
"info": "",
"category": "camera",
"in": [
{
"x": 100,
"y": 180,
"wires": [
{
"id": "a1a8e6ff.f8ac4"
}
]
}
],
"out": [
{
"x": 960,
"y": 140,
"wires": [
{
"id": "793d24ac.8a4d7c",
"port": 0
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
},
{
"name": "device_id",
"type": "str",
"value": ""
},
{
"name": "device_name",
"type": "str",
"value": ""
},
{
"name": "user_id",
"type": "env",
"value": "ALOES_USER_ID"
},
{
"name": "store_type",
"type": "env",
"value": "NODE_RED_STORE_TYPE"
}
],
"inputLabels": [
"->camera"
],
"outputLabels": [
"camera->"
],
"icon": "font-awesome/fa-desktop",
"status": {
"x": 980,
"y": 260,
"wires": [
{
"id": "1065b7b.be2cd48",
"port": 0
}
]
}
},
{
"id": "d9f5cfe5.63ebc8",
"type": "ui_button",
"z": "35404dde.e62b92",
"name": "PUT/sensor/3349/2/5911",
"group": "85023e56.3ce8c",
"order": 2,
"width": "3",
"height": "1",
"passthru": false,
"label": "capture",
"tooltip": "request a picture",
"color": "",
"bgcolor": "",
"icon": "",
"payload": "true",
"payloadType": "bool",
"topic": "",
"x": 290,
"y": 840,
"wires": [
[
"a906ae9c.baf4f"
]
]
},
{
"id": "c76eb306.919998",
"type": "ui_template",
"z": "35404dde.e62b92",
"group": "85023e56.3ce8c",
"name": "image-out",
"order": 3,
"width": "6",
"height": "5",
"format": "<!DOCTYPE html>\n<div id=\"{{'stream-view-'+$id}}\">\n <img id=\"{{'stream-viewer-'+$id}}\" style=\"{{'max-width:100%'}}\" src=\"{{$imageUrl}}\">\n</div>\n<script>\n(function(scope) {\n scope.$watch('msg', (msg) => {\n try {\n scope.$imageUrl = \"\";\n if (msg && msg.payload) {\n let blob;\n let payload = msg.payload;\n let contentType = \"png\";\n if (msg.mimetype) contentType = msg.mimetype;\n // console.log(\"new pic for camera\", payload, typeof payload);\n //console.log(\"isBuffer?\", payload instanceof Buffer);\n if (payload && typeof payload === 'string') {\n const base64Flag = `data:image/${contentType};base64,`;\n blob = (fetch(`${base64Flag}${payload}`)).blob();\n } else if (payload.type && payload.type === 'Buffer') {\n blob = new Blob([Uint8Array.from(payload.data)], { type: contentType });\n } else if (payload instanceof ArrayBuffer) {\n blob = new Blob([payload], { type: contentType });\n } else {\n blob = new Blob([Uint8Array.from(payload)], { type: contentType });\n } \n if (!blob) throw new Error(\"No Blob\");\n blob.lastModifiedDate = new Date();\n blob.name = \"camera-2\";\n // console.log(\"new blob for camera\", blob)\n const urlCreator = window.URL || window.webkitURL;\n scope.$imageUrl = urlCreator.createObjectURL(blob);\n msg.payload = blob;\n return msg;\n }\n return null;\n } catch(error){\n return error;\n }\n });\n})(scope);\n</script>",
"storeOutMessages": false,
"fwdInMessages": true,
"templateScope": "local",
"x": 490,
"y": 1000,
"wires": [
[]
]
},
{
"id": "ea9cbbe3.f4a41",
"type": "subflow:2188cc9a.23fde4",
"z": "35404dde.e62b92",
"name": "",
"env": [
{
"name": "store_type",
"type": "env",
"value": "store_type"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
}
],
"x": 980,
"y": 840,
"wires": [
[
"2afe8254.d1496e"
]
]
},
{
"id": "671d7a2e.e76374",
"type": "file",
"z": "35404dde.e62b92",
"name": "",
"filename": "",
"appendNewline": false,
"createDir": false,
"overwriteFile": "true",
"encoding": "none",
"x": 330,
"y": 1060,
"wires": [
[
"c76eb306.919998"
]
]
},
{
"id": "78fd3f2e.f1ab38",
"type": "comment",
"z": "35404dde.e62b92",
"name": "Sensor properties",
"info": "",
"x": 170,
"y": 760,
"wires": []
},
{
"id": "eb00e129.0ce0e",
"type": "comment",
"z": "35404dde.e62b92",
"name": "FLOW INPUT",
"info": "",
"x": 150,
"y": 40,
"wires": []
},
{
"id": "80cde71.772bb18",
"type": "comment",
"z": "35404dde.e62b92",
"name": "FLOW OUTPUT",
"info": "",
"x": 880,
"y": 60,
"wires": []
},
{
"id": "793d24ac.8a4d7c",
"type": "link in",
"z": "35404dde.e62b92",
"name": "subflow-output",
"links": [
"2afe8254.d1496e"
],
"x": 815,
"y": 140,
"wires": [
[]
]
},
{
"id": "2afe8254.d1496e",
"type": "link out",
"z": "35404dde.e62b92",
"name": "updated-instance->",
"links": [
"793d24ac.8a4d7c"
],
"x": 1135,
"y": 840,
"wires": []
},
{
"id": "498e42fb.c0cef4",
"type": "subflow:de56f8d.072c908",
"z": "35404dde.e62b92",
"name": "",
"env": [
{
"name": "method",
"type": "str",
"value": "PUT"
},
{
"name": "sensor_id",
"type": "str",
"value": "2"
},
{
"name": "object_id",
"type": "str",
"value": "3349"
},
{
"name": "resource_id",
"type": "str",
"value": "5911"
}
],
"x": 780,
"y": 840,
"wires": [
[
"ea9cbbe3.f4a41"
]
]
},
{
"id": "4fa8f5ec.73e484",
"type": "link in",
"z": "35404dde.e62b92",
"name": "SWITCH/3349/2/5911",
"links": [
"7f81c9ca.0b627",
"9d5bfded.2f42e",
"36c3c817.4ff89",
"9c0948e.e3d0638"
],
"x": 95,
"y": 840,
"wires": [
[
"d9f5cfe5.63ebc8"
]
]
},
{
"id": "854d8a03.53f7a",
"type": "link in",
"z": "35404dde.e62b92",
"name": "IMAGE/3349/2/5910",
"links": [
"4c8eac63.9f287c",
"e3b47f22.b1b7a8",
"cb3efedb.ac0f6"
],
"x": 100,
"y": 1000,
"wires": [
[
"c76eb306.919998"
]
]
},
{
"id": "2ffe6e30.892b7a",
"type": "ui_switch",
"z": "35404dde.e62b92",
"name": "camera-2-selection",
"label": "{{msg.label}}",
"tooltip": "{{msg.tooltip}}",
"group": "18dbcafd.0bd0d5",
"order": 2,
"width": "3",
"height": "1",
"passthru": false,
"decouple": "true",
"topic": "",
"style": "",
"onvalue": "true",
"onvalueType": "bool",
"onicon": "",
"oncolor": "",
"offvalue": "false",
"offvalueType": "bool",
"officon": "",
"offcolor": "",
"x": 930,
"y": 600,
"wires": [
[
"7c6d0972.7eb1b8"
]
]
},
{
"id": "c5c55c1e.41e5c8",
"type": "ui_template",
"z": "35404dde.e62b92",
"group": "18dbcafd.0bd0d5",
"name": "camera-2-status",
"order": 1,
"width": "6",
"height": "1",
"format": "<!DOCTYPE html>\n<svg viewBox=\"0 0 270 40\" id=\"{{'devices-status-'+ $id}}\">\n <text x=\"0\" y=\"25\" style=\"{{'font-weight:700'}}\" >{{$deviceName}}</text>\n <image\n id=\"{{'device-icon-'+$id}}\" \n x=\"200\"\n y=\"2\"\n width=\"35px\" \n height=\"35px\"\n preserveAspectRatio=\"xMidYMin slice\"\n xlink:href=\"{{ $getImageUrl() }}\"></image>\n <circle id=\"{{'devices-status-icon-'+$id}}\" x=\"0\" y=\"0\" cx=\"265\" cy=\"20\" r=\"15\" fill=\"{{$statusColor}}\" ></circle>\n</svg>\n<script>\n(function(scope) {\n scope.$watch('msg', (msg) => {\n try{\n scope.$statusText = \"Waiting\";\n scope.$deviceName = \"\";\n scope.$statusColor = \"#ff4500\";\n scope.$getImageUrl = () => {\n const icon = scope.$deviceIcon || \"\";\n return icon;\n }\n if (msg && msg.device) {\n scope.$deviceName = msg.device.name;\n scope.$deviceIcon = msg.device.icons[0];\n if (msg && (msg.device.status === true || msg.device.status === \"true\")) {\n scope.$statusColor = \"#baff00\";\n scope.$statusText = \"Ready\";\n }\n }\n // return msg;\n } catch(error){\n return error;\n }\n \n });\n})(scope);\n</script>",
"storeOutMessages": false,
"fwdInMessages": false,
"templateScope": "local",
"x": 290,
"y": 640,
"wires": [
[]
]
},
{
"id": "7c6d0972.7eb1b8",
"type": "subflow:32f8e46a.971f8c",
"z": "35404dde.e62b92",
"name": "",
"env": [
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "store_type",
"type": "str",
"value": "file"
}
],
"x": 1160,
"y": 600,
"wires": [
[
"f12db90.2d6a5c8"
]
]
},
{
"id": "c291ea34.44f14",
"type": "change",
"z": "35404dde.e62b92",
"name": "devicesSelection",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "#:(file)::devicesSelection",
"tot": "global"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 290,
"y": 600,
"wires": [
[
"16183248.b827be"
]
]
},
{
"id": "f12db90.2d6a5c8",
"type": "subflow:8ff67ce6.9014f",
"z": "35404dde.e62b92",
"name": "",
"env": [
{
"name": "label_true",
"type": "str",
"value": "Remove"
},
{
"name": "tooltip_true",
"type": "str",
"value": "Remove from device selection"
},
{
"name": "topic_true",
"type": "str",
"value": "DELETE/devicesSelection"
},
{
"name": "payload_true",
"type": "bool",
"value": "true"
},
{
"name": "label_false",
"type": "str",
"value": "Add"
},
{
"name": "tooltip_false",
"type": "str",
"value": "Add to device selection"
},
{
"name": "topic_false",
"type": "str",
"value": "POST/devicesSelection"
},
{
"name": "payload_false",
"type": "bool",
"value": "false"
}
],
"x": 720,
"y": 600,
"wires": [
[
"2ffe6e30.892b7a"
]
]
},
{
"id": "31a62a09.60811e",
"type": "comment",
"z": "35404dde.e62b92",
"name": "Device properties",
"info": "",
"x": 170,
"y": 540,
"wires": []
},
{
"id": "d794e94b.bef6b8",
"type": "link in",
"z": "35404dde.e62b92",
"name": "->filter-device",
"links": [
"e6825b5.72ce0a8",
"eb7f5978.6ca228",
"763c5d2f.362884"
],
"x": 95,
"y": 600,
"wires": [
[
"c291ea34.44f14",
"c5c55c1e.41e5c8",
"4bef8c61.75a084"
]
]
},
{
"id": "a1a8e6ff.f8ac4",
"type": "subflow:1be19fb.0ff37e",
"z": "35404dde.e62b92",
"name": "",
"env": [],
"x": 260,
"y": 180,
"wires": [
[
"763c5d2f.362884"
],
[
"35072de6.697922"
],
[
"476906e5.f2206"
]
]
},
{
"id": "35072de6.697922",
"type": "switch",
"z": "35404dde.e62b92",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 520,
"y": 160,
"wires": [
[
"cb3efedb.ac0f6"
],
[
"cb3efedb.ac0f6"
],
[],
[
"108a84da.9b0753"
]
]
},
{
"id": "108a84da.9b0753",
"type": "link out",
"z": "35404dde.e62b92",
"name": "0/3349/1/5910",
"links": [],
"x": 675,
"y": 180,
"wires": []
},
{
"id": "cb3efedb.ac0f6",
"type": "link out",
"z": "35404dde.e62b92",
"name": "1/3349/1/5910",
"links": [
"854d8a03.53f7a"
],
"x": 675,
"y": 140,
"wires": []
},
{
"id": "476906e5.f2206",
"type": "switch",
"z": "35404dde.e62b92",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 520,
"y": 240,
"wires": [
[
"36c3c817.4ff89"
],
[
"36c3c817.4ff89"
],
[],
[
"9c0948e.e3d0638"
]
]
},
{
"id": "9c0948e.e3d0638",
"type": "link out",
"z": "35404dde.e62b92",
"name": "0/3349/1/5911",
"links": [
"4fa8f5ec.73e484"
],
"x": 675,
"y": 260,
"wires": []
},
{
"id": "36c3c817.4ff89",
"type": "link out",
"z": "35404dde.e62b92",
"name": "1/3349/1/5911",
"links": [
"4fa8f5ec.73e484"
],
"x": 675,
"y": 220,
"wires": []
},
{
"id": "763c5d2f.362884",
"type": "link out",
"z": "35404dde.e62b92",
"name": "device-properties->",
"links": [
"d794e94b.bef6b8"
],
"x": 420,
"y": 80,
"wires": []
},
{
"id": "4bef8c61.75a084",
"type": "change",
"z": "35404dde.e62b92",
"name": "description",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "device.description",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 270,
"y": 680,
"wires": [
[
"af0664c5.7de808"
]
]
},
{
"id": "af0664c5.7de808",
"type": "ui_text",
"z": "35404dde.e62b92",
"group": "85023e56.3ce8c",
"order": 1,
"width": "12",
"height": "1",
"name": "description",
"label": "",
"format": "{{msg.payload || \"\" }}",
"layout": "row-left",
"x": 450,
"y": 680,
"wires": []
},
{
"id": "16183248.b827be",
"type": "subflow:41c6c6f2.febed8",
"z": "35404dde.e62b92",
"name": "",
"env": [],
"x": 500,
"y": 600,
"wires": [
[
"f12db90.2d6a5c8"
]
]
},
{
"id": "641d0c0e.91b41c",
"type": "inject",
"z": "35404dde.e62b92",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "10",
"crontab": "",
"once": true,
"onceDelay": "5",
"x": 170,
"y": 1440,
"wires": [
[
"4ce0c075.354a2",
"27f3cfd1.047628"
]
]
},
{
"id": "e22cceee.c9c88",
"type": "inject",
"z": "35404dde.e62b92",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": "2",
"x": 170,
"y": 1260,
"wires": [
[
"17124e.f1739db2"
]
]
},
{
"id": "4c8871ea.3f4c8",
"type": "ui_template",
"z": "35404dde.e62b92",
"group": "85023e56.3ce8c",
"name": "camera-2-qrcode",
"order": 4,
"width": "3",
"height": "4",
"format": "<!DOCTYPE html>\n<div id=\"{{'qrcode-view-'+$id}}\">\n <p> {{ $label }} </p>\n <img id=\"{{'qrcode-viewer-'+$id}}\" style=\"{{'max-width:100%'}}\" src=\"{{$imageUrl}}\">\n</div>\n<script>\n(function(scope) {\n scope.$watch('msg', (msg) => {\n try {\n scope.$imageUrl = \"\";\n if (msg && msg.qrCodeAddress) {\n let blob;\n let payload = msg.qrCodeAddress;\n let contentType = \"png\";\n const deviceName = \"aloes-device\";\n scope.$label = 'IOTA address : ';\n scope.$deviceName = deviceName;\n if (msg.mimetype) contentType = msg.mimetype;\n // console.log(`new pic for ${deviceName}`, payload, typeof payload);\n if (payload && typeof payload === 'string') {\n scope.$imageUrl = payload;\n return msg;\n // const base64Flag = `data:image/${contentType};base64,`;\n // blob = (fetch(`${base64Flag}${payload}`)).blob();\n } else if (payload.type && payload.type === 'Buffer') {\n blob = new Blob([Uint8Array.from(payload.data)], { type: `image/${contentType}` });\n } else if (payload instanceof ArrayBuffer) {\n blob = new Blob([payload], { type: `image/${contentType}` });\n } else if (payload instanceof Array){\n blob = new Blob([Uint8Array.from(payload)], { type: `image/${contentType}`});\n } else {\n throw new Error(\"No valid payload to transform to blob\");\n }\n if (!blob) throw new Error(\"No Blob\");\n blob.lastModifiedDate = new Date();\n blob.name = deviceName;\n // console.log(`new blob for ${deviceName}`, blob)\n const urlCreator = window.URL || window.webkitURL;\n scope.$imageUrl = urlCreator.createObjectURL(blob);\n msg.payload = blob;\n // return msg;\n } \n if (msg && msg.transactions) {\n scope.$label = msg.label ? msg.label : 'Transaction ongoing ...';\n scope.$imageUrl = `/icons/on.png`;\n }\n return null;;\n } catch(error){\n return error;\n }\n });\n})(scope);\n</script>",
"storeOutMessages": false,
"fwdInMessages": true,
"templateScope": "local",
"x": 690,
"y": 1480,
"wires": [
[]
]
},
{
"id": "591d400c.8dbdf8",
"type": "ui_text",
"z": "35404dde.e62b92",
"group": "85023e56.3ce8c",
"order": 6,
"width": "4",
"height": "1",
"name": "",
"label": "IOTA balance",
"format": "{{msg.service.currentIotaBalance || 0}}",
"layout": "row-spread",
"x": 680,
"y": 1380,
"wires": []
},
{
"id": "a54ad17.20c58b",
"type": "ui_text",
"z": "35404dde.e62b92",
"group": "85023e56.3ce8c",
"order": 7,
"width": "4",
"height": "1",
"name": "",
"label": "IOTA price",
"format": "{{msg.payload}}",
"layout": "row-spread",
"x": 670,
"y": 1560,
"wires": []
},
{
"id": "af0d5f2c.bf2cd",
"type": "comment",
"z": "35404dde.e62b92",
"name": "Scenario",
"info": "",
"x": 140,
"y": 1180,
"wires": []
},
{
"id": "17124e.f1739db2",
"type": "subflow:7c29baf0.0afbdc",
"z": "35404dde.e62b92",
"name": "",
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"x": 430,
"y": 1260,
"wires": [
[]
]
},
{
"id": "27f3cfd1.047628",
"type": "subflow:2cff5c49.cc97e4",
"z": "35404dde.e62b92",
"name": "",
"env": [],
"x": 410,
"y": 1440,
"wires": [
[
"591d400c.8dbdf8",
"661822f3.ef3fcc"
],
[
"4c8871ea.3f4c8"
],
[
"4c8871ea.3f4c8"
]
]
},
{
"id": "4ce0c075.354a2",
"type": "change",
"z": "35404dde.e62b92",
"name": "iota-price",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "iota-price-dollar",
"tot": "global"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 400,
"y": 1560,
"wires": [
[
"a54ad17.20c58b"
]
]
},
{
"id": "e980279b.8b86",
"type": "ui_toast",
"z": "35404dde.e62b92",
"position": "top right",
"displayTime": "3",
"highlight": "",
"outputs": 0,
"ok": "OK",
"cancel": "",
"topic": "",
"name": "",
"x": 810,
"y": 900,
"wires": []
},
{
"id": "661822f3.ef3fcc",
"type": "ui_text",
"z": "35404dde.e62b92",
"group": "85023e56.3ce8c",
"order": 5,
"width": "4",
"height": "1",
"name": "",
"label": "Device balance",
"format": "{{msg.service.currentBalance || 0}}",
"layout": "row-spread",
"x": 680,
"y": 1420,
"wires": []
},
{
"id": "a322e29b.c40668",
"type": "subflow:c8603d46.4fae9",
"z": "35404dde.e62b92",
"name": "",
"env": [
{
"name": "debug",
"type": "bool",
"value": "true"
}
],
"x": 580,
"y": 920,
"wires": [
[
"498e42fb.c0cef4"
],
[
"e980279b.8b86"
]
]
},
{
"id": "1065b7b.be2cd48",
"type": "status",
"z": "35404dde.e62b92",
"name": "",
"scope": [
"27f3cfd1.047628",
"a322e29b.c40668",
"17124e.f1739db2",
"16183248.b827be"
],
"x": 860,
"y": 260,
"wires": [
[]
]
},
{
"id": "a906ae9c.baf4f",
"type": "function",
"z": "35404dde.e62b92",
"name": "check-device-status",
"func": "\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 440,
"y": 880,
"wires": [
[]
]
},
{
"id": "85023e56.3ce8c",
"type": "ui_group",
"z": "35404dde.e62b92",
"name": "camera-2",
"tab": "fe99d4b2.836eb",
"order": 2,
"disp": true,
"width": "12",
"collapse": true
},
{
"id": "f156cee.223b33",
"type": "subflow",
"name": "generate-seed",
"info": "",
"category": "iota",
"in": [
{
"x": 200,
"y": 140,
"wires": [
{
"id": "bfe2a004.85f408"
}
]
}
],
"out": [
{
"x": 920,
"y": 140,
"wires": [
{
"id": "fa9ff963.199dd",
"port": 0
}
]
}
],
"env": [
{
"name": "ALOES_USER_ID",
"type": "env",
"value": "ALOES_USER_ID"
}
]
},
{
"id": "bfe2a004.85f408",
"type": "exec",
"z": "f156cee.223b33",
"command": "cat /dev/urandom |tr -dc A-Z9|head -c${1:-81}",
"addpay": false,
"append": "",
"useSpawn": "false",
"timer": "",
"oldrc": false,
"name": "generate-random-seed",
"x": 390,
"y": 140,
"wires": [
[
"fa9ff963.199dd"
],
[],
[]
]
},
{
"id": "fa9ff963.199dd",
"type": "function",
"z": "f156cee.223b33",
"name": "update-seeds-index",
"func": " \ntry {\n const ownerId = env.get(\"ALOES_USER_ID\");\n const seed = msg.payload;\n let seedsIndex = {};\n global.get(\"seeds-index\", \"file\", (err, res) => {\n if (err) throw err;\n seedsIndex = res || {};\n });\n console.log(\"SEED LENGTH : \", seed.length);\n\n if (seed && seed.length === 81 && ownerId) {\n if (seedsIndex[seed]) {\n seedsIndex[seed].id = seed;\n seedsIndex[seed].ownerId = ownerId;\n } else {\n seedsIndex[seed] = {id : seed, ownerId};\n }\n }\n console.log(\"SEEDS INDEX : \", seedsIndex);\n global.set(\"seeds-index\", seedsIndex, \"file\", err => {\n if (err) throw err;\n });\n return msg;\n} catch(error) {\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 740,
"y": 140,
"wires": [
[]
]
},
{
"id": "f3e81342.4218a8",
"type": "subflow",
"name": "filter-sensor-ids",
"info": "",
"category": "aloes",
"in": [
{
"x": 120,
"y": 140,
"wires": [
{
"id": "df258731.d4091"
}
]
}
],
"out": [
{
"x": 520,
"y": 140,
"wires": [
{
"id": "df258731.d4091",
"port": 0
}
]
}
],
"env": [
{
"name": "sensor_ids",
"type": "json",
"value": "[\"1\"]"
}
]
},
{
"id": "df258731.d4091",
"type": "function",
"z": "f3e81342.4218a8",
"name": "filter-sensors",
"func": "const sensorIds = msg.sensorIds || env.get(\"sensor_ids\");\nif (!sensorIds || sensorIds === null) return null;\nif ( msg.sensor && msg.sensor.nativeSensorId && msg.sensor.resources) {\n const nativeSensorId = msg.sensor.nativeSensorId;\n const foundSensorId = sensorIds.some(id => id === nativeSensorId); \n if (foundSensorId) {\n return msg;\n }\n}\nreturn null;",
"outputs": 1,
"noerr": 0,
"x": 310,
"y": 140,
"wires": [
[]
]
},
{
"id": "9df057d3.045cf",
"type": "subflow",
"name": "get-account-infos",
"info": "",
"category": "iota",
"in": [
{
"x": 120,
"y": 200,
"wires": [
{
"id": "109bcc56.80288c"
}
]
}
],
"out": [
{
"x": 840,
"y": 200,
"wires": [
{
"id": "86f652d4.1b373",
"port": 0
}
]
}
],
"env": [
{
"name": "IOTA_SEED",
"type": "str",
"value": ""
},
{
"name": "debug",
"type": "bool",
"value": "true"
}
],
"status": {
"x": 840,
"y": 80,
"wires": [
{
"id": "e6c8c22f.fa3c38",
"port": 0
}
]
}
},
{
"id": "109bcc56.80288c",
"type": "subflow:bbb4a70e.34bed8",
"z": "9df057d3.045cf",
"name": "",
"env": [
{
"name": "modules",
"type": "json",
"value": "[\"iota-api\"]"
}
],
"x": 330,
"y": 200,
"wires": [
[
"86f652d4.1b373"
]
]
},
{
"id": "86f652d4.1b373",
"type": "function",
"z": "9df057d3.045cf",
"name": "get-account-data",
"func": "try {\n if (!msg || !msg.payload) throw new Error(\"No IOTA dependencies found\");\n const iota = msg.payload[\"iota-api\"];\n if (!iota || iota === null) throw new Error(\"Cannot get IOTA API\");\n const debug = env.get(\"debug\");\n const seed = msg.seed || env.get(\"IOTA_SEED\");\n if (!seed || seed === null) throw new Error(\"Account seed empty\");\n\n // iota.getAccountData(seed, {start: 0, security: 2}, (err, res) => {\n // if (err) throw err;\n // console.log(\"account data: \", res);\n // })\n\n iota.getInputs(seed, { start: 0, threshold: 100 })\n .then(res => {\n msg.inputs = res;\n node.send(msg);\n node.status({fill:\"green\",shape:\"ring\",text:\"account-get\"});\n if (debug) {\n console.log(\"account inputs: \", res);\n }\n return res;\n })\n .catch(err => {\n if (debug && err.message === errors.INSUFFICIENT_BALANCE) {\n console.log(\"account insufficient balance: \", err.message);\n }\n throw error;\n });\n \n return msg;\n} catch(error) {\n node.status({fill:\"red\",shape:\"ring\",text:\"account-get-error\"});\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 570,
"y": 200,
"wires": [
[
"38b85a8a.89313e"
]
]
},
{
"id": "38b85a8a.89313e",
"type": "debug",
"z": "9df057d3.045cf",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"x": 610,
"y": 280,
"wires": []
},
{
"id": "e6c8c22f.fa3c38",
"type": "status",
"z": "9df057d3.045cf",
"name": "",
"scope": null,
"x": 600,
"y": 80,
"wires": [
[]
]
},
{
"id": "4ed2b2eb.efb33c",
"type": "subflow",
"name": "parse-transactions",
"info": "",
"category": "iota",
"in": [
{
"x": 80,
"y": 140,
"wires": [
{
"id": "ac063a78.7b9498"
}
]
}
],
"out": [
{
"x": 920,
"y": 140,
"wires": [
{
"id": "cb6ad3a1.dd17f8",
"port": 0
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"status": {
"x": 760,
"y": 60,
"wires": [
{
"id": "10c08265.fe8976",
"port": 0
}
]
}
},
{
"id": "ac063a78.7b9498",
"type": "subflow:bbb4a70e.34bed8",
"z": "4ed2b2eb.efb33c",
"name": "",
"env": [
{
"name": "modules",
"type": "json",
"value": "[\"iota-api\", \"iota-extract-json\"]"
}
],
"x": 250,
"y": 140,
"wires": [
[
"e2bd5e4a.db3fd8"
]
]
},
{
"id": "10c08265.fe8976",
"type": "status",
"z": "4ed2b2eb.efb33c",
"name": "",
"scope": null,
"x": 540,
"y": 60,
"wires": [
[]
]
},
{
"id": "e2bd5e4a.db3fd8",
"type": "function",
"z": "4ed2b2eb.efb33c",
"name": "parse-transactions",
"func": "try {\n const iota = msg.payload[\"iota-api\"];\n if (!iota || iota === null) throw new Error(\"Cannot get IOTA API\");\n const extract = msg.payload[\"iota-extract-json\"];\n if (!extract || extract === null) throw new Error(\"Cannot get IOTA extractJson module\");\n if (!msg.transactions || msg.transactions === null) throw new Error(\"Missing transactions\");\n const debug = env.get('debug');\n \n const hashes = msg.transactions;\n hashes.forEach((hash, index) => {\n iota.getBundle(hash)\n .then(bundle => {\n let message = extract.extractJson(bundle);\n message = JSON.parse(message);\n delete message.sensorId;\n delete message.ownerId;\n message.timestamp = bundle[0].timestamp;\n // message.address = bundle[0].address;\n if (debug) {\n // console.log(\"transactions bundle : \", bundle);\n console.log(\"transactions message 2 : \", message);\n }\n \n if (index === hashes.length -1) {\n node.send({complete: true, payload : message });\n } else {\n node.send({payload: message });\n }\n node.status({fill:\"green\",shape:\"ring\",text:\"transactions-parse\"});\n return bundle;\n })\n .catch(err => err)\n });\n \n return null;\n} catch(error) {\n node.status({fill:\"red\",shape:\"ring\",text:\"transactions-parse-error\"});\n if (debug) {\n console.log(\"transactions err : \", error);\n }\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 530,
"y": 140,
"wires": [
[
"cb6ad3a1.dd17f8"
]
]
},
{
"id": "cb6ad3a1.dd17f8",
"type": "join",
"z": "4ed2b2eb.efb33c",
"name": "",
"mode": "custom",
"build": "array",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": false,
"timeout": "",
"count": "msg.payload.length",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 750,
"y": 140,
"wires": [
[]
]
},
{
"id": "293e18ad.f29c48",
"type": "subflow:9df057d3.045cf",
"z": "4ed2b2eb.efb33c",
"name": "",
"x": 300,
"y": 300,
"wires": [
[]
]
},
{
"id": "62434896.a030b8",
"type": "subflow",
"name": "create-transaction",
"info": "",
"category": "iota",
"in": [
{
"x": 160,
"y": 140,
"wires": [
{
"id": "b32d2ec8.2c7d68"
}
]
}
],
"out": [
{
"x": 800,
"y": 140,
"wires": [
{
"id": "8f7ed981.96c88",
"port": 0
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "true"
},
{
"name": "IOTA_SEED",
"type": "env",
"value": "IOTA_SEED"
},
{
"name": "address",
"type": "str",
"value": ""
},
{
"name": "tag",
"type": "str",
"value": ""
},
{
"name": "message",
"type": "str",
"value": ""
},
{
"name": "value",
"type": "num",
"value": ""
}
],
"status": {
"x": 800,
"y": 60,
"wires": [
{
"id": "96236190.5d38b",
"port": 0
}
]
}
},
{
"id": "b32d2ec8.2c7d68",
"type": "subflow:bbb4a70e.34bed8",
"z": "62434896.a030b8",
"name": "",
"env": [
{
"name": "modules",
"type": "json",
"value": "[\"iota-api\", \"iota-converter\"]"
}
],
"x": 350,
"y": 140,
"wires": [
[
"8f7ed981.96c88"
]
]
},
{
"id": "8f7ed981.96c88",
"type": "function",
"z": "62434896.a030b8",
"name": "test-transaction",
"func": "try {\n const debug = env.get('debug');\n if (!msg || !msg.payload) throw new Error(\"No IOTA dependencies found\");\n const iota = msg.payload[\"iota-api\"];\n if (!iota || iota === null) throw new Error(\"Cannot get IOTA API instance\");\n const Converter = msg.payload[\"iota-converter\"];\n if (!Converter || Converter === null) throw new Error(\"Cannot get IOTA Converter module\");\n const seed = env.get(\"IOTA_SEED\");\n if (!seed || seed === null) throw new Error(\"Missing IOTA seed\");\n const address = msg.address || env.get(\"address\");\n if (!address || address === null) throw new Error(\"Missing IOTA address\");\n \n const tag = msg.tag || env.get(\"tag\");\n let message = msg.message || env.get(\"message\");\n if (message && message !== null) {\n message = Converter.asciiToTrytes(message);\n }\n let value = msg.value || env.get(\"value\") || 0;\n const depth = global.get(\"iota-depth\") || 3;\n const mwm = global.get(\"iota-mwm\") || 9;\n \n const transfers = [{\n value,\n address,\n message, \n // tag\n }];\n if (debug) {\n console.log('transfers to send: ', transfers[0]);\n }\n\n iota.prepareTransfers(seed, transfers)\n .then(trytes => iota.sendTrytes(trytes, depth, mwm))\n .then(bundle => {\n if (debug) {\n console.log(`Bundle: ${JSON.stringify(bundle, null, 1)}`)\n }\n msg.bundle = bundle;\n node.send(msg);\n node.status({fill: 'green', shape: 'ring', text: 'transaction-create'});\n return bundle;\n })\n\n return null;\n} catch(error) {\n node.status({fill: 'red', shape: 'ring', text: 'transaction-create-error'});\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 600,
"y": 140,
"wires": [
[]
]
},
{
"id": "96236190.5d38b",
"type": "status",
"z": "62434896.a030b8",
"name": "",
"scope": null,
"x": 560,
"y": 60,
"wires": [
[]
]
},
{
"id": "ec8f2af7.5cbfb",
"type": "subflow",
"name": "set-buffer-array",
"info": "",
"category": "function",
"in": [
{
"x": 220,
"y": 180,
"wires": [
{
"id": "e9025a0c.9810e8"
}
]
}
],
"out": [
{
"x": 520,
"y": 180,
"wires": [
{
"id": "e9025a0c.9810e8",
"port": 0
}
]
}
],
"env": [
{
"name": "resource_id",
"type": "str",
"value": ""
},
{
"name": "debug",
"type": "bool",
"value": "true"
}
],
"icon": "font-awesome/fa-check"
},
{
"id": "e9025a0c.9810e8",
"type": "function",
"z": "ec8f2af7.5cbfb",
"name": "setArrayBuffer",
"func": "try {\n const debug = env.get(\"debug\");\n const resourceId = env.get(\"resource_id\");\n if (!resourceId) throw new Error(\"no resource id set\");\n const value = msg.sensor.resources[resourceId]; // const value = msg.sensor.value;\n if (!value) throw new Error(\"no sensor value found\");\n if (debug) {\n console.log(\"get array buffer from type :\", value, typeof value);\n }\n if (typeof value === \"string\") {\n if ( value === \"1\" || value === \"true\") return null;\n msg.payload = Buffer.from(value, 'base64').toJSON().data; \n if (debug) {\n console.log(\"set array buffer from string:\", msg.payload);\n }\n } else if (typeof value === \"object\" && value.type && value.data){\n // msg.payload = value.data;\n msg.payload = Buffer.from(value);\n msg.payload = msg.payload.toString('utf-8');\n } else if (Buffer.isBuffer(value)){\n msg.payload = value;\n } else {\n return null;\n }\n if (debug) {\n console.log(\"set array buffer :\", msg.payload);\n }\n return msg;\n} catch(error) {\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 360,
"y": 180,
"wires": [
[]
]
},
{
"id": "4bb4beb2.33adc8",
"type": "subflow",
"name": "rfid-scanner-logic",
"info": "**rfid-scanner-logic**\n\n- Plug it after a aloes-client node\n- Set device_name and device id ( from your Aloes account)\n- Output whole device object and sensor properties \n",
"category": "rfid-scanners",
"in": [
{
"x": 100,
"y": 160,
"wires": [
{
"id": "2fa65f47.708048"
}
]
}
],
"out": [
{
"x": 900,
"y": 140,
"wires": [
{
"id": "4113efe.739e81",
"port": 0
}
]
},
{
"x": 900,
"y": 420,
"wires": [
{
"id": "e8412019.eb477",
"port": 0
}
]
},
{
"x": 900,
"y": 460,
"wires": [
{
"id": "e8412019.eb477",
"port": 1
}
]
},
{
"x": 900,
"y": 540,
"wires": [
{
"id": "5b6b1781.f1c7f8",
"port": 0
}
]
},
{
"x": 900,
"y": 580,
"wires": [
{
"id": "5b6b1781.f1c7f8",
"port": 1
}
]
},
{
"x": 540,
"y": 160,
"wires": [
{
"id": "2fa65f47.708048",
"port": 2
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "true"
},
{
"name": "device_id",
"type": "env",
"value": "device_id"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "store_type",
"type": "env",
"value": "store_type"
}
],
"outputLabels": [
"device-properties",
"*/3306/*/5850",
"*/3306/*/5851",
"*/3341/*/5527",
"*/3341/*/5527",
"measurements"
],
"icon": "node-red/batch.png"
},
{
"id": "cf4d29d8.a03878",
"type": "switch",
"z": "4bb4beb2.33adc8",
"name": "objectId",
"property": "sensor.type",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "3306",
"vt": "num"
},
{
"t": "eq",
"v": "3341",
"vt": "num"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 420,
"y": 480,
"wires": [
[
"e8412019.eb477"
],
[
"5b6b1781.f1c7f8"
]
]
},
{
"id": "e8412019.eb477",
"type": "switch",
"z": "4bb4beb2.33adc8",
"name": "3306-resourceId",
"property": "sensor.resource",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "5850",
"vt": "str"
},
{
"t": "eq",
"v": "5851",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 670,
"y": 440,
"wires": [
[],
[]
]
},
{
"id": "3e3345cf.8f2c02",
"type": "switch",
"z": "4bb4beb2.33adc8",
"name": "5850-sensorId",
"property": "sensor.nativeSensorId",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "1",
"vt": "str"
},
{
"t": "eq",
"v": "2",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 900,
"y": 320,
"wires": [
[],
[]
]
},
{
"id": "4d2fcba9.8e13ac",
"type": "switch",
"z": "4bb4beb2.33adc8",
"name": "5851-sensorId",
"property": "sensor.nativeSensorId",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "1",
"vt": "str"
},
{
"t": "eq",
"v": "2",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 900,
"y": 360,
"wires": [
[],
[]
]
},
{
"id": "23bf9fa4.f2ec8",
"type": "debug",
"z": "4bb4beb2.33adc8",
"name": "${device_name}",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"x": 240,
"y": 240,
"wires": []
},
{
"id": "2fa65f47.708048",
"type": "subflow:744e75eb.cf669c",
"z": "4bb4beb2.33adc8",
"name": "",
"env": [],
"x": 250,
"y": 160,
"wires": [
[
"e42b35c6.65a52"
],
[
"725b7d65.0eefd4"
],
[],
[],
[
"ce867b6b.43529"
],
[
"23bf9fa4.f2ec8"
]
]
},
{
"id": "5b6b1781.f1c7f8",
"type": "switch",
"z": "4bb4beb2.33adc8",
"name": "3341-resourceId",
"property": "sensor.resource",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "5527",
"vt": "str"
},
{
"t": "eq",
"v": "5851",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 670,
"y": 560,
"wires": [
[],
[]
]
},
{
"id": "4dd9d19.7b35db",
"type": "switch",
"z": "4bb4beb2.33adc8",
"name": "5527-sensorId",
"property": "sensor.nativeSensorId",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "3",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 1,
"x": 1100,
"y": 300,
"wires": [
[]
]
},
{
"id": "e9bcf37f.6e98e8",
"type": "comment",
"z": "4bb4beb2.33adc8",
"name": "FLOW INPUT",
"info": "",
"x": 150,
"y": 60,
"wires": []
},
{
"id": "725b7d65.0eefd4",
"type": "link out",
"z": "4bb4beb2.33adc8",
"name": "filter-sensors->",
"links": [
"c96fb061.ab2cb8"
],
"x": 475,
"y": 120,
"wires": []
},
{
"id": "c96fb061.ab2cb8",
"type": "link in",
"z": "4bb4beb2.33adc8",
"name": "->filter-sensors",
"links": [
"725b7d65.0eefd4",
"4e41e9b7.9fcf68"
],
"x": 95,
"y": 480,
"wires": [
[
"7da0d6be.4c2648"
]
]
},
{
"id": "4113efe.739e81",
"type": "link in",
"z": "4bb4beb2.33adc8",
"name": "->updated-instance",
"links": [
"e42b35c6.65a52",
"7983b16a.756e4"
],
"x": 795,
"y": 140,
"wires": [
[]
]
},
{
"id": "8fa1edc.b81571",
"type": "comment",
"z": "4bb4beb2.33adc8",
"name": "FLOW OUTPUT",
"info": "",
"x": 860,
"y": 40,
"wires": []
},
{
"id": "86a7b51a.e0e4b8",
"type": "comment",
"z": "4bb4beb2.33adc8",
"name": "Filter sensor properties",
"info": "",
"x": 180,
"y": 320,
"wires": []
},
{
"id": "cbd8e03.8f583a",
"type": "inject",
"z": "4bb4beb2.33adc8",
"name": "refreshViews",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "60",
"crontab": "",
"once": true,
"onceDelay": "30",
"x": 160,
"y": 1080,
"wires": [
[]
]
},
{
"id": "1411f5a5.f07b72",
"type": "comment",
"z": "4bb4beb2.33adc8",
"name": "Refresh interfaces",
"info": "",
"x": 170,
"y": 1040,
"wires": []
},
{
"id": "b15093c.985e67",
"type": "subflow:8a55823f.f6ad1",
"z": "4bb4beb2.33adc8",
"name": "get-sensor-3306-1",
"env": [
{
"name": "object_id",
"type": "str",
"value": "3306"
}
],
"x": 250,
"y": 1240,
"wires": [
[
"4e41e9b7.9fcf68"
]
]
},
{
"id": "fc232908.4ceb6",
"type": "subflow:8a55823f.f6ad1",
"z": "4bb4beb2.33adc8",
"name": "get-sensor-3306-2",
"env": [
{
"name": "object_id",
"type": "str",
"value": "3306"
},
{
"name": "sensor_id",
"type": "str",
"value": "2"
}
],
"x": 250,
"y": 1300,
"wires": [
[
"4e41e9b7.9fcf68"
]
]
},
{
"id": "4e41e9b7.9fcf68",
"type": "link out",
"z": "4bb4beb2.33adc8",
"name": "filter-sensors->",
"links": [
"c96fb061.ab2cb8"
],
"x": 435,
"y": 1240,
"wires": []
},
{
"id": "e42b35c6.65a52",
"type": "link out",
"z": "4bb4beb2.33adc8",
"name": "filter-device->",
"links": [
"4113efe.739e81"
],
"x": 475,
"y": 80,
"wires": []
},
{
"id": "71cb3ee2.746e8",
"type": "subflow:8a55823f.f6ad1",
"z": "4bb4beb2.33adc8",
"name": "get-sensor-3341-3",
"env": [
{
"name": "object_id",
"type": "str",
"value": "3341"
},
{
"name": "sensor_id",
"type": "str",
"value": "3"
}
],
"x": 250,
"y": 1360,
"wires": [
[
"4e41e9b7.9fcf68"
]
]
},
{
"id": "750f70ef.bb2548",
"type": "subflow:ec8f2af7.5cbfb",
"z": "4bb4beb2.33adc8",
"name": "",
"env": [
{
"name": "resource_id",
"type": "str",
"value": "5527"
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"x": 800,
"y": 660,
"wires": [
[]
]
},
{
"id": "76c9ffbe.33e4e",
"type": "subflow:d253d97e.e3e448",
"z": "4bb4beb2.33adc8",
"name": "get-device-rfid-scanner",
"env": [],
"x": 270,
"y": 1180,
"wires": [
[
"7983b16a.756e4"
]
]
},
{
"id": "7983b16a.756e4",
"type": "link out",
"z": "4bb4beb2.33adc8",
"name": "filter-device->",
"links": [
"4113efe.739e81"
],
"x": 435,
"y": 1180,
"wires": []
},
{
"id": "e2f84520.8c942",
"type": "comment",
"z": "4bb4beb2.33adc8",
"name": "Filter triggers",
"info": "",
"x": 150,
"y": 800,
"wires": []
},
{
"id": "323fc550.8c98d2",
"type": "link in",
"z": "4bb4beb2.33adc8",
"name": "->filter-triggers",
"links": [
"ce867b6b.43529"
],
"x": 95,
"y": 880,
"wires": [
[
"df3dd3e1.188ce8"
]
]
},
{
"id": "df3dd3e1.188ce8",
"type": "switch",
"z": "4bb4beb2.33adc8",
"name": "Command",
"property": "trigger",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "refresh",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 1,
"x": 350,
"y": 880,
"wires": [
[
"44f928a6.3905a"
]
]
},
{
"id": "44f928a6.3905a",
"type": "switch",
"z": "4bb4beb2.33adc8",
"name": "Collection",
"property": "collection",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "sensor",
"vt": "str"
},
{
"t": "eq",
"v": "device",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 600,
"y": 880,
"wires": [
[
"55c099ad.37729"
],
[
"7fc8b3f4.042904"
]
]
},
{
"id": "55c099ad.37729",
"type": "link out",
"z": "4bb4beb2.33adc8",
"name": "trigger-refresh-sensor->",
"links": [
"f5ce4202.0550b"
],
"x": 855,
"y": 840,
"wires": []
},
{
"id": "7fc8b3f4.042904",
"type": "link out",
"z": "4bb4beb2.33adc8",
"name": "trigger-refresh-device->",
"links": [
"57986700.11d28"
],
"x": 855,
"y": 920,
"wires": []
},
{
"id": "57986700.11d28",
"type": "link in",
"z": "4bb4beb2.33adc8",
"name": "->trigger-refresh-device",
"links": [
"7fc8b3f4.042904"
],
"x": 95,
"y": 1180,
"wires": [
[
"76c9ffbe.33e4e"
]
]
},
{
"id": "ce867b6b.43529",
"type": "link out",
"z": "4bb4beb2.33adc8",
"name": "filter-triggers->",
"links": [
"323fc550.8c98d2"
],
"x": 475,
"y": 220,
"wires": []
},
{
"id": "f5ce4202.0550b",
"type": "link in",
"z": "4bb4beb2.33adc8",
"name": "->trigger-refresh-sensors",
"links": [
"55c099ad.37729"
],
"x": 95,
"y": 1240,
"wires": [
[
"b15093c.985e67",
"fc232908.4ceb6",
"71cb3ee2.746e8"
]
]
},
{
"id": "7da0d6be.4c2648",
"type": "change",
"z": "4bb4beb2.33adc8",
"name": "",
"rules": [
{
"t": "set",
"p": "method",
"pt": "msg",
"to": "parts[2]",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 240,
"y": 480,
"wires": [
[
"cf4d29d8.a03878"
]
]
},
{
"id": "84450db6.23247",
"type": "subflow",
"name": "rfid-scanner-2",
"info": "",
"category": "rfid-scanners",
"in": [
{
"x": 100,
"y": 420,
"wires": [
{
"id": "9b486211.ea495"
}
]
}
],
"out": [
{
"x": 1160,
"y": 140,
"wires": [
{
"id": "7793dc1b.1e716c",
"port": 0
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
},
{
"name": "device_id",
"type": "str",
"value": ""
},
{
"name": "device_name",
"type": "str",
"value": ""
},
{
"name": "user_id",
"type": "env",
"value": "ALOES_USER_ID"
},
{
"name": "store_type",
"type": "env",
"value": "NODE_RED_STORE_TYPE"
}
],
"icon": "font-awesome/fa-desktop",
"status": {
"x": 1160,
"y": 200,
"wires": [
{
"id": "9101173d.30f",
"port": 0
}
]
}
},
{
"id": "823048b3.8d5d8",
"type": "subflow:2188cc9a.23fde4",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "store_type",
"type": "env",
"value": "store_type"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
}
],
"x": 1020,
"y": 1100,
"wires": [
[
"5b10cf5d.ee9c4"
]
]
},
{
"id": "874dde58.214bd",
"type": "ui_switch",
"z": "84450db6.23247",
"name": "PUT/sensor/3306/1/5850",
"label": "switch",
"tooltip": "Turn on/off relay",
"group": "dd9158e0.7c0c2",
"order": 2,
"width": "6",
"height": "1",
"passthru": false,
"decouple": "false",
"topic": "",
"style": "",
"onvalue": "true",
"onvalueType": "bool",
"onicon": "",
"oncolor": "",
"offvalue": "false",
"offvalueType": "bool",
"officon": "",
"offcolor": "",
"x": 470,
"y": 1100,
"wires": [
[
"7d0a63bc.ade7ec"
]
]
},
{
"id": "dd51cde0.68302",
"type": "ui_text",
"z": "84450db6.23247",
"group": "dd9158e0.7c0c2",
"order": 3,
"width": "12",
"height": "1",
"name": "",
"label": "Read tag",
"format": "{{msg.sensor.value}}",
"layout": "row-spread",
"x": 480,
"y": 1260,
"wires": []
},
{
"id": "4962a1b3.ba858",
"type": "comment",
"z": "84450db6.23247",
"name": "FLOW INPUT",
"info": "",
"x": 150,
"y": 60,
"wires": []
},
{
"id": "5b10cf5d.ee9c4",
"type": "link out",
"z": "84450db6.23247",
"name": "updated-instance->",
"links": [
"7793dc1b.1e716c"
],
"x": 1175,
"y": 1100,
"wires": []
},
{
"id": "4c87a2dc.9c2acc",
"type": "link in",
"z": "84450db6.23247",
"name": "TEXT/3341/2/5527",
"links": [
"385f1cfc.2a2ef4"
],
"x": 115,
"y": 1260,
"wires": [
[
"dd51cde0.68302"
]
]
},
{
"id": "7793dc1b.1e716c",
"type": "link in",
"z": "84450db6.23247",
"name": "->updated-instance",
"links": [
"5b10cf5d.ee9c4",
"6ff09ee0.9e5e38"
],
"x": 1035,
"y": 140,
"wires": [
[]
]
},
{
"id": "dd042c82.4f3aa8",
"type": "comment",
"z": "84450db6.23247",
"name": "FLOW OUTPUT",
"info": "",
"x": 1100,
"y": 80,
"wires": []
},
{
"id": "59ddd5b8.70116c",
"type": "comment",
"z": "84450db6.23247",
"name": "Sensor properties",
"info": "",
"x": 190,
"y": 960,
"wires": []
},
{
"id": "bc982f81.928b6",
"type": "link in",
"z": "84450db6.23247",
"name": "SWITCH/3306/1/5850",
"links": [
"1041c986.6b4c86",
"a0c9679c.9e255"
],
"x": 115,
"y": 1100,
"wires": [
[
"e960a5fe.3aab3"
]
]
},
{
"id": "7d0a63bc.ade7ec",
"type": "subflow:de56f8d.072c908",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "method",
"type": "str",
"value": "PUT"
},
{
"name": "object_id",
"type": "str",
"value": "3306"
},
{
"name": "resource_id",
"type": "str",
"value": "5850"
}
],
"x": 700,
"y": 1100,
"wires": [
[
"823048b3.8d5d8"
]
]
},
{
"id": "3855e78.38cdb18",
"type": "subflow:de56f8d.072c908",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "method",
"type": "str",
"value": "PUT"
},
{
"name": "sensor_id",
"type": "str",
"value": "4"
},
{
"name": "object_id",
"type": "str",
"value": "3341"
},
{
"name": "resource_id",
"type": "str",
"value": "5527"
}
],
"x": 860,
"y": 1180,
"wires": [
[
"823048b3.8d5d8"
]
]
},
{
"id": "e960a5fe.3aab3",
"type": "subflow:1e071b74.a346dd",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "resource_id",
"type": "str",
"value": "5850"
}
],
"x": 230,
"y": 1100,
"wires": [
[
"874dde58.214bd"
]
]
},
{
"id": "34907f12.71f2c",
"type": "ui_switch",
"z": "84450db6.23247",
"name": "rfid-scanner-2-selection",
"label": "{{msg.label}}",
"tooltip": "{{msg.tooltip}}",
"group": "18dbcafd.0bd0d5",
"order": 8,
"width": "3",
"height": "1",
"passthru": false,
"decouple": "true",
"topic": "",
"style": "",
"onvalue": "true",
"onvalueType": "bool",
"onicon": "",
"oncolor": "",
"offvalue": "false",
"offvalueType": "bool",
"officon": "",
"offcolor": "",
"x": 950,
"y": 800,
"wires": [
[
"9ede80e9.442428"
]
]
},
{
"id": "49d8c5dc.96a814",
"type": "ui_template",
"z": "84450db6.23247",
"group": "18dbcafd.0bd0d5",
"name": "rfid-scanner-2-status",
"order": 7,
"width": "6",
"height": "1",
"format": "<!DOCTYPE html>\n<svg viewBox=\"0 0 270 40\" id=\"{{'devices-status-'+ $id}}\">\n <text x=\"0\" y=\"25\" style=\"{{'font-weight:700'}}\" >{{$deviceName}}</text>\n <image\n id=\"{{'device-icon-'+$id}}\" \n x=\"200\"\n y=\"2\"\n width=\"35px\" \n height=\"35px\"\n preserveAspectRatio=\"xMidYMin slice\"\n xlink:href=\"{{ $getImageUrl() }}\"></image>\n <circle id=\"{{'devices-status-icon-'+$id}}\" x=\"0\" y=\"0\" cx=\"265\" cy=\"20\" r=\"15\" fill=\"{{$statusColor}}\" ></circle>\n</svg>\n<script>\n(function(scope) {\n scope.$watch('msg', (msg) => {\n try{\n scope.$statusText = \"Waiting\";\n scope.$deviceName = \"\";\n scope.$statusColor = \"#ff4500\";\n scope.$getImageUrl = () => {\n const icon = scope.$deviceIcon || \"\";\n return icon;\n }\n if (msg && msg.device) {\n scope.$deviceName = msg.device.name;\n scope.$deviceIcon = msg.device.icons[0];\n if (msg && (msg.device.status === true || msg.device.status === \"true\")) {\n scope.$statusColor = \"#baff00\";\n scope.$statusText = \"Ready\";\n }\n }\n // return msg;\n } catch(error){\n return error;\n }\n \n });\n})(scope);\n</script>",
"storeOutMessages": false,
"fwdInMessages": false,
"templateScope": "local",
"x": 320,
"y": 840,
"wires": [
[]
]
},
{
"id": "9ede80e9.442428",
"type": "subflow:32f8e46a.971f8c",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "store_type",
"type": "str",
"value": "file"
}
],
"x": 1190,
"y": 800,
"wires": [
[
"430095f8.4bbdfc"
]
]
},
{
"id": "6837784d.77a618",
"type": "change",
"z": "84450db6.23247",
"name": "devicesSelection",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "#:(file)::devicesSelection",
"tot": "global"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 310,
"y": 800,
"wires": [
[
"318cbd3f.67dcfa"
]
]
},
{
"id": "430095f8.4bbdfc",
"type": "subflow:8ff67ce6.9014f",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "label_true",
"type": "str",
"value": "Remove"
},
{
"name": "tooltip_true",
"type": "str",
"value": "Remove from device selection"
},
{
"name": "topic_true",
"type": "str",
"value": "DELETE/devicesSelection"
},
{
"name": "payload_true",
"type": "bool",
"value": "true"
},
{
"name": "label_false",
"type": "str",
"value": "Add"
},
{
"name": "tooltip_false",
"type": "str",
"value": "Add to device selection"
},
{
"name": "topic_false",
"type": "str",
"value": "POST/devicesSelection"
},
{
"name": "payload_false",
"type": "bool",
"value": "false"
}
],
"x": 730,
"y": 800,
"wires": [
[
"34907f12.71f2c"
]
]
},
{
"id": "340aa316.68efdc",
"type": "link in",
"z": "84450db6.23247",
"name": "->filter-device",
"links": [
"f460d91a.631598"
],
"x": 115,
"y": 800,
"wires": [
[
"6837784d.77a618",
"49d8c5dc.96a814",
"dd18077a.dd26e"
]
]
},
{
"id": "fe200cfb.235cc",
"type": "comment",
"z": "84450db6.23247",
"name": "Device properties",
"info": "",
"x": 190,
"y": 720,
"wires": []
},
{
"id": "1041c986.6b4c86",
"type": "link out",
"z": "84450db6.23247",
"name": "1/3306/1/5850",
"links": [
"bc982f81.928b6"
],
"x": 1195,
"y": 320,
"wires": []
},
{
"id": "385f1cfc.2a2ef4",
"type": "link out",
"z": "84450db6.23247",
"name": "1/3341/3/5527",
"links": [
"4c87a2dc.9c2acc",
"aa2e1da8.a8c548"
],
"x": 1195,
"y": 460,
"wires": []
},
{
"id": "a0c9679c.9e255",
"type": "link out",
"z": "84450db6.23247",
"name": "0/3306/1/5850",
"links": [
"bc982f81.928b6"
],
"x": 1195,
"y": 360,
"wires": []
},
{
"id": "bb85aba8.2572a",
"type": "switch",
"z": "84450db6.23247",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 1000,
"y": 340,
"wires": [
[
"1041c986.6b4c86"
],
[
"1041c986.6b4c86"
],
[],
[
"a0c9679c.9e255"
]
]
},
{
"id": "e4fee301.cc9c78",
"type": "switch",
"z": "84450db6.23247",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 1000,
"y": 480,
"wires": [
[
"385f1cfc.2a2ef4"
],
[
"385f1cfc.2a2ef4"
],
[],
[
"ba4da2bc.1a902"
]
]
},
{
"id": "ba4da2bc.1a902",
"type": "link out",
"z": "84450db6.23247",
"name": "0/3341/3/5527",
"links": [],
"x": 1195,
"y": 500,
"wires": []
},
{
"id": "f460d91a.631598",
"type": "link out",
"z": "84450db6.23247",
"name": "device-properties->",
"links": [
"340aa316.68efdc"
],
"x": 300,
"y": 280,
"wires": []
},
{
"id": "9b486211.ea495",
"type": "subflow:4bb4beb2.33adc8",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"x": 250,
"y": 420,
"wires": [
[
"f460d91a.631598"
],
[
"66c5ea42.f7ab34"
],
[],
[
"14616f4d.d9fa71"
],
[],
[]
]
},
{
"id": "aa2e1da8.a8c548",
"type": "link in",
"z": "84450db6.23247",
"name": "->1/3341/2/5527",
"links": [
"385f1cfc.2a2ef4"
],
"x": 115,
"y": 1780,
"wires": [
[
"74d10c81.ce5dac"
]
]
},
{
"id": "ea2d110b.2f10e8",
"type": "comment",
"z": "84450db6.23247",
"name": "Scenario",
"info": "",
"x": 160,
"y": 1420,
"wires": []
},
{
"id": "846cf15f.c61018",
"type": "switch",
"z": "84450db6.23247",
"name": "",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "178,143,190,121",
"vt": "str"
},
{
"t": "eq",
"v": "208,248,191,164",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "true",
"repair": false,
"outputs": 3,
"x": 270,
"y": 2140,
"wires": [
[
"21d1eb0f.24aedc"
],
[
"fad6c1ce.e778b8"
],
[
"512b5bc1.3544fc"
]
]
},
{
"id": "21d1eb0f.24aedc",
"type": "change",
"z": "84450db6.23247",
"name": "PUT/sensor/3306/1/5850",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "PUT/sensor/3306/1/5850",
"tot": "str"
},
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "false",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 690,
"y": 2120,
"wires": [
[
"ecb0daee.d56898"
]
]
},
{
"id": "ecb0daee.d56898",
"type": "subflow:2188cc9a.23fde4",
"z": "84450db6.23247",
"name": "relay-3",
"env": [
{
"name": "store_type",
"type": "env",
"value": "store_type"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "device_name",
"type": "str",
"value": "relay-3"
}
],
"x": 980,
"y": 2120,
"wires": [
[
"6ff09ee0.9e5e38"
]
]
},
{
"id": "6ff09ee0.9e5e38",
"type": "link out",
"z": "84450db6.23247",
"name": "device-out->",
"links": [
"7793dc1b.1e716c"
],
"x": 1175,
"y": 1780,
"wires": []
},
{
"id": "512b5bc1.3544fc",
"type": "change",
"z": "84450db6.23247",
"name": "PUT/sensor/3306/1/5850",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "PUT/sensor/3306/1/5850",
"tot": "str"
},
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "false",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 690,
"y": 2220,
"wires": [
[
"ecb0daee.d56898"
]
]
},
{
"id": "fad6c1ce.e778b8",
"type": "change",
"z": "84450db6.23247",
"name": "PUT/sensor/3306/1/5850",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "PUT/sensor/3306/1/5850",
"tot": "str"
},
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "true",
"tot": "bool"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 690,
"y": 2160,
"wires": [
[]
]
},
{
"id": "dd18077a.dd26e",
"type": "change",
"z": "84450db6.23247",
"name": "description",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "device.description",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 290,
"y": 880,
"wires": [
[
"53390cc3.b2b5d4"
]
]
},
{
"id": "53390cc3.b2b5d4",
"type": "ui_text",
"z": "84450db6.23247",
"group": "dd9158e0.7c0c2",
"order": 1,
"width": "12",
"height": "1",
"name": "description",
"label": "",
"format": "{{msg.payload || \"\" }}",
"layout": "row-left",
"x": 470,
"y": 880,
"wires": []
},
{
"id": "318cbd3f.67dcfa",
"type": "subflow:41c6c6f2.febed8",
"z": "84450db6.23247",
"name": "",
"env": [],
"x": 520,
"y": 800,
"wires": [
[
"430095f8.4bbdfc"
]
]
},
{
"id": "9101173d.30f",
"type": "status",
"z": "84450db6.23247",
"name": "",
"scope": [
"9ff293b0.125448",
"37134c96.e93804"
],
"x": 1060,
"y": 200,
"wires": [
[]
]
},
{
"id": "37134c96.e93804",
"type": "subflow:62434896.a030b8",
"z": "84450db6.23247",
"name": "",
"env": [],
"x": 590,
"y": 2400,
"wires": [
[]
]
},
{
"id": "dfa3a67d.c4d3b",
"type": "function",
"z": "84450db6.23247",
"name": "prepare-transaction",
"func": " \ntry {\n const deviceId = env.get('device_id');\n if (!deviceId || deviceId === null) throw new Error('Missing device id');\n if (!msg || !msg.sensor || msg.sensor === null) throw new Error('Missing sensor instance');\n const storeType = 'file';\n let service;\n global.get(`service-${deviceId}`, storeType, (err,res) => {\n if (err) throw err;\n service = res;\n });\n if (!service || service === null) throw new Error('Service not found');\n msg.address = service.currentIotaAddress;\n console.log(\"service transaction : \", service);\n\n delete msg.sensor.resources;\n const message = {\n tagId: msg.sensor.value, \n sensorId: msg.sensor.id, \n deviceId: msg.sensor.deviceId, \n ownerId: msg.sensor.ownerId\n }\n msg.message = JSON.stringify(message);\n msg.tag = `${msg.sensor.ownerId}`;\n msg.value = 0;\n console.log(\"message to send : \", msg.message);\n return msg;\n} catch(error) {\n console.log(\"service transaction err: \", error);\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 320,
"y": 2400,
"wires": [
[
"37134c96.e93804"
]
]
},
{
"id": "39eb723.081320e",
"type": "inject",
"z": "84450db6.23247",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": "2",
"x": 190,
"y": 1500,
"wires": [
[
"9ff293b0.125448"
]
]
},
{
"id": "9ff293b0.125448",
"type": "subflow:7c29baf0.0afbdc",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"x": 450,
"y": 1500,
"wires": [
[]
]
},
{
"id": "5725fe88.bbfbf8",
"type": "subflow:e30ce4bf.a549b8",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "debug",
"type": "bool",
"value": "true"
}
],
"x": 630,
"y": 1580,
"wires": [
[
"f062d4a0.a17b28"
]
]
},
{
"id": "f062d4a0.a17b28",
"type": "subflow:4ed2b2eb.efb33c",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "debug",
"type": "bool",
"value": "true"
}
],
"x": 870,
"y": 1580,
"wires": [
[
"a698caad.f4a52"
]
]
},
{
"id": "18e3985d.ad9cf8",
"type": "function",
"z": "84450db6.23247",
"name": "get-iota-address",
"func": " \ntry {\n const deviceId = env.get('device_id');\n if (!deviceId || deviceId === null) throw new Error('Missing device id');\n const storeType = 'file';\n let service;\n global.get(`service-${deviceId}`, storeType, (err,res) => {\n if (err) throw err;\n service = res;\n });\n if (!service || service === null) throw new Error('Service not found');\n \n msg.address = service.currentIotaAddress;\n return msg;\n} catch(error) {\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 390,
"y": 1580,
"wires": [
[
"5725fe88.bbfbf8"
]
]
},
{
"id": "c4f01cf4.47ed3",
"type": "inject",
"z": "84450db6.23247",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "30",
"crontab": "",
"once": true,
"onceDelay": "5",
"x": 190,
"y": 1580,
"wires": [
[]
]
},
{
"id": "a698caad.f4a52",
"type": "ui_template",
"z": "84450db6.23247",
"group": "dd9158e0.7c0c2",
"name": "transactions-display",
"order": 5,
"width": "12",
"height": "8",
"format": "<!DOCTYPE html>\n<div id=\"{{'transactions-table-'+$id}}\" class=\"transaction-tables\" style=\"{{'width: 100%'}}\">\n <p id=\"{{'show-table-'+$id}}\"></p>\n</div>\n<style>\n div.transaction-tables {\n font-size:12px ;\n }\n div.transaction-tables > table, th, td {\n border: solid 1px #DDD;\n border-collapse: collapse;\n padding: 2px 3px;\n text-align: center;\n width: 100%;\n }\n div.transaction-tables > table > tbody > tr > th {\n font-weight: bold;\n background-color: #F2F2F2;\n }\n</style>\n<script>\n(function(scope) {\n const buildTable = (transactions) => {\n try {\n const col = [];\n for (let i = 0; i < transactions.length; i++) {\n for (let key in transactions[i]) {\n if (col.indexOf(key) === -1) {\n col.push(key);\n }\n }\n }\n \n const table = document.createElement(\"table\");\n let tr = table.insertRow(-1); // TABLE ROW.\n for (let i = 0; i < col.length; i++) {\n const th = document.createElement(\"th\"); // TABLE HEADER.\n th.innerHTML = col[i];\n tr.appendChild(th);\n }\n \n for (let i = 0; i < transactions.length; i++) {\n tr = table.insertRow(-1);\n for (let j = 0; j < col.length; j++) {\n const tabCell = tr.insertCell(-1);\n tabCell.innerHTML = transactions[i][col[j]];\n }\n }\n const divContainer = document.getElementById(`transactions-table-${scope.$id}`);\n divContainer.innerHTML = \"\";\n divContainer.appendChild(table);\n return divContainer;\n } catch(error) {\n // console.log(\"transactions display err: \", error);\n return error;\n }\n }\n \n scope.$watch('msg', (msg) => {\n try {\n scope.$transactions = [];\n if (msg && msg.payload) {\n scope.$transactions = msg.payload;\n buildTable(scope.$transactions);\n return msg;\n }\n return null;\n } catch(error){\n return error;\n }\n });\n})(scope);\n</script>",
"storeOutMessages": true,
"fwdInMessages": false,
"templateScope": "local",
"x": 1100,
"y": 1580,
"wires": [
[]
]
},
{
"id": "7be40e69.bdbe1",
"type": "ui_text_input",
"z": "84450db6.23247",
"name": "",
"label": "Write tag",
"tooltip": "Enter the value that will be sent to write on detected tag",
"group": "dd9158e0.7c0c2",
"order": 4,
"width": 0,
"height": 0,
"passthru": false,
"mode": "text",
"delay": "0",
"topic": "",
"x": 480,
"y": 1180,
"wires": [
[
"98f1f77.73fae08"
]
]
},
{
"id": "66c5ea42.f7ab34",
"type": "change",
"z": "84450db6.23247",
"name": "getSensorIds",
"rules": [
{
"t": "set",
"p": "sensorIds",
"pt": "msg",
"to": "sensors-3306",
"tot": "flow"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 500,
"y": 380,
"wires": [
[
"be7236fa.afd5f8"
]
]
},
{
"id": "be7236fa.afd5f8",
"type": "subflow:f3e81342.4218a8",
"z": "84450db6.23247",
"name": "filter-switches",
"env": [],
"x": 670,
"y": 380,
"wires": [
[
"b201e196.2737f"
]
]
},
{
"id": "b201e196.2737f",
"type": "switch",
"z": "84450db6.23247",
"name": "sensorId",
"property": "sensor.nativeSensorId",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "1",
"vt": "str"
},
{
"t": "eq",
"v": "2",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 820,
"y": 380,
"wires": [
[
"bb85aba8.2572a"
],
[]
]
},
{
"id": "fcd853ac.defc18",
"type": "inject",
"z": "84450db6.23247",
"name": "set switch sensors",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"x": 190,
"y": 140,
"wires": [
[
"72e7ca00.50411"
]
]
},
{
"id": "c9ea6baf.a7a34",
"type": "inject",
"z": "84450db6.23247",
"name": "set text sensors",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"x": 180,
"y": 180,
"wires": [
[
"4689515.e7cddb"
]
]
},
{
"id": "4689515.e7cddb",
"type": "change",
"z": "84450db6.23247",
"name": "sensors-3341",
"rules": [
{
"t": "set",
"p": "sensors-3341",
"pt": "flow",
"to": "[\"3\",\"4\"]",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 420,
"y": 180,
"wires": [
[]
]
},
{
"id": "72e7ca00.50411",
"type": "change",
"z": "84450db6.23247",
"name": "sensors-3306",
"rules": [
{
"t": "set",
"p": "sensors-3306",
"pt": "flow",
"to": "[\"1\",\"2\"]",
"tot": "json"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 420,
"y": 140,
"wires": [
[]
]
},
{
"id": "2d9a93e.bc8ebec",
"type": "subflow:f3e81342.4218a8",
"z": "84450db6.23247",
"name": "filter-texts",
"env": [
{
"name": "sensor_ids",
"type": "str",
"value": ""
}
],
"x": 660,
"y": 520,
"wires": [
[
"2c36ae8f.94aa2a"
]
]
},
{
"id": "14616f4d.d9fa71",
"type": "change",
"z": "84450db6.23247",
"name": "getSensorIds",
"rules": [
{
"t": "set",
"p": "sensorIds",
"pt": "msg",
"to": "sensors-3341",
"tot": "flow"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 500,
"y": 520,
"wires": [
[
"2d9a93e.bc8ebec"
]
]
},
{
"id": "2c36ae8f.94aa2a",
"type": "switch",
"z": "84450db6.23247",
"name": "sensorId",
"property": "sensor.nativeSensorId",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "3",
"vt": "str"
},
{
"t": "eq",
"v": "4",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 820,
"y": 520,
"wires": [
[
"e4fee301.cc9c78"
],
[
"b1dc1a40.e1499"
]
]
},
{
"id": "ff9c7ca0.e06de",
"type": "link out",
"z": "84450db6.23247",
"name": "1/3341/3/5527",
"links": [],
"x": 1195,
"y": 560,
"wires": []
},
{
"id": "b1dc1a40.e1499",
"type": "switch",
"z": "84450db6.23247",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 1000,
"y": 580,
"wires": [
[
"ff9c7ca0.e06de"
],
[
"ff9c7ca0.e06de"
],
[],
[
"ff7f1045.6fcce8"
]
]
},
{
"id": "ff7f1045.6fcce8",
"type": "link out",
"z": "84450db6.23247",
"name": "0/3341/3/5527",
"links": [],
"x": 1195,
"y": 600,
"wires": []
},
{
"id": "415dace3.d66884",
"type": "comment",
"z": "84450db6.23247",
"name": "Registering each readings in the tangle",
"info": "",
"x": 370,
"y": 2360,
"wires": []
},
{
"id": "9276c60e.b896c8",
"type": "change",
"z": "84450db6.23247",
"name": "PUT/sensor/3341/4/5527",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "PUT/sensor/3341/4/5527",
"tot": "str"
},
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "write-tag",
"tot": "flow"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 490,
"y": 1780,
"wires": [
[
"aa4b2bb9.fd44c"
]
]
},
{
"id": "98f1f77.73fae08",
"type": "change",
"z": "84450db6.23247",
"name": "write-tag",
"rules": [
{
"t": "set",
"p": "write-tag",
"pt": "flow",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 700,
"y": 1180,
"wires": [
[]
]
},
{
"id": "8f0a244e.d1fd48",
"type": "subflow:2188cc9a.23fde4",
"z": "84450db6.23247",
"name": "",
"env": [
{
"name": "store_type",
"type": "env",
"value": "store_type"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
}
],
"x": 920,
"y": 1780,
"wires": [
[
"6ff09ee0.9e5e38",
"b9102b77.616c"
]
]
},
{
"id": "b9102b77.616c",
"type": "debug",
"z": "84450db6.23247",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"x": 1140,
"y": 1740,
"wires": []
},
{
"id": "aa4b2bb9.fd44c",
"type": "delay",
"z": "84450db6.23247",
"name": "",
"pauseType": "delay",
"timeout": "2",
"timeoutUnits": "seconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 680,
"y": 1780,
"wires": [
[
"8f0a244e.d1fd48"
]
]
},
{
"id": "5c0291d4.413648",
"type": "comment",
"z": "84450db6.23247",
"name": "Check if value is a known tag",
"info": "",
"x": 240,
"y": 1720,
"wires": []
},
{
"id": "74d10c81.ce5dac",
"type": "function",
"z": "84450db6.23247",
"name": "parse-tag",
"func": "try {\n const parts = msg.payload.split('-');\n if (!parts.length || parts.length < 2) return [msg, null]; \n msg.tagUid = parts[0];\n msg.tagSeed = parts[1];\n let seedIndex;\n global.get(\"seed-index\", \"file\", (err, res) => {\n if (err) throw err;\n seedIndex = res;\n });\n let seedFound = false;\n let tagUidFound = false;\n if (seedIndex && seedIndex !== null) {\n Object.keys(seedIndex).forEach(seed => {\n if (msg.tagSeed === seed) {\n seedFound = true;\n const seedRegister = seedIndex[seed];\n if (seedRegister.tags && seedRegister.tags.some(tag => tag === msg.tagUid)) {\n tagUidFound = true;\n return;\n }\n return;\n }\n return;\n });\n console.log(\"Tag found ? \", tagUidFound);\n console.log(\"Seed found ? \", seedFound);\n if (tagUidFound && seedFound) {\n return [null, msg]\n }\n }\n return [msg, null]; \n} catch(error) {\n return error;\n}\n",
"outputs": 2,
"noerr": 0,
"x": 220,
"y": 1780,
"wires": [
[
"9276c60e.b896c8"
],
[
"e32759d8.5fce88"
]
]
},
{
"id": "e32759d8.5fce88",
"type": "subflow:9df057d3.045cf",
"z": "84450db6.23247",
"name": "",
"env": [],
"x": 460,
"y": 1840,
"wires": [
[]
]
},
{
"id": "599c7a27.f4fa24",
"type": "subflow:f156cee.223b33",
"z": "84450db6.23247",
"name": "",
"env": [],
"x": 460,
"y": 1900,
"wires": [
[]
]
},
{
"id": "dd9158e0.7c0c2",
"type": "ui_group",
"z": "84450db6.23247",
"name": "rfid-scanner-2",
"tab": "fe99d4b2.836eb",
"order": 5,
"disp": true,
"width": "12",
"collapse": true
},
{
"id": "7c29baf0.0afbdc",
"type": "subflow",
"name": "create-iota-service",
"info": "",
"category": "iota",
"in": [
{
"x": 100,
"y": 140,
"wires": [
{
"id": "fcadc148.015bc"
}
]
}
],
"out": [
{
"x": 1060,
"y": 140,
"wires": [
{
"id": "7d218795.4241a",
"port": 0
},
{
"id": "a792f83e.20bed8",
"port": 1
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "true"
},
{
"name": "IOTA_SEED",
"type": "env",
"value": "IOTA_SEED"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "device_id",
"type": "env",
"value": "device_id"
},
{
"name": "store_type",
"type": "str",
"value": "file"
}
],
"status": {
"x": 1060,
"y": 40,
"wires": [
{
"id": "4fc61f50.483b98",
"port": 0
}
]
}
},
{
"id": "c298808a.1f2ec8",
"type": "subflow:76b7192.e6e5de8",
"z": "7c29baf0.0afbdc",
"name": "",
"env": [
{
"name": "IOTA_ADDRESS_SECURITY",
"type": "num",
"value": "2"
},
{
"name": "debug",
"type": "env",
"value": "debug"
}
],
"x": 620,
"y": 100,
"wires": [
[
"7d218795.4241a"
]
]
},
{
"id": "fcadc148.015bc",
"type": "function",
"z": "7c29baf0.0afbdc",
"name": "get-iota-service",
"func": "const debug = env.get(\"debug\");\n\nconst findOrCreateService = (msg, deviceId, storeType) => {\n try {\n let service;\n global.get(`service-${deviceId}`, storeType, (err, res) => {\n if (err) throw err;\n service = res || null; \n if (debug) {\n console.log(\"Found Service\", service);\n }\n });\n if (!service || service === null) {\n service = { \n currentIotaAddress: '', \n currentIotaBalance: 0, \n lastIotaBalance: 0, \n currentBalance: 0,\n transactionsCount: 0\n };\n if (debug) {\n console.log(\"Init new Service\", service);\n }\n }\n\n msg.service = service;\n if (service.currentIotaAddress && service.currentIotaAddress !== null) {\n node.send(msg);\n node.status({fill:\"green\",shape:\"ring\",text:\"address-get\"});\n } else {\n if (!msg.addressIndex || msg.addressIndex === null) {\n const d = new Date();\n msg.addressIndex = d.getTime();\n }\n msg.addressSecurity = 1;\n node.send(msg);\n node.status({fill:\"yellow\",shape:\"ring\",text:\"address-create-in-progress\"});\n }\n return null;\n } catch(error) {\n return error;\n }\n}\n\ntry {\n const storeType = env.get('store_type');\n const deviceId = env.get('device_id');\n if (!deviceId || deviceId === null) throw new Error(\"Missing device id\");\n findOrCreateService(msg, deviceId, storeType);\n return null;\n} catch(error) {\n node.status({fill:\"green\",shape:\"ring\",text:\"address-get-error\"});\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 260,
"y": 140,
"wires": [
[
"a792f83e.20bed8"
]
]
},
{
"id": "7d218795.4241a",
"type": "function",
"z": "7c29baf0.0afbdc",
"name": "set-iota-service",
"func": "try {\n const storeType = env.get('store_type');\n const deviceId = env.get('device_id');\n if (!deviceId || deviceId === null) throw new Error(\"Device id's missing\");\n if (!msg || !msg.address || msg.address === null) throw new Error(\"no address to save\");\n if (!msg || !msg.service || msg.service === null) throw new Error(\"no service to update\");\n const debug = env.get(\"debug\");\n msg.service.currentIotaAddress = msg.address;\n if (debug) {\n console.log(\"Set IOTA Address\", msg.service);\n }\n \n global.set(`service-${deviceId}`, msg.service, storeType, (err) => {\n if (err) throw err;\n });\n // global.set(`iota-address-${env.get('device_name')}`, msg.address, 'file', err => {\n // if (err) throw err;\n // });\n msg.payload = msg.address;\n node.status({fill:\"green\",shape:\"ring\",text:\"address-set\"});\n return msg;\n} catch(error) {\n node.status({fill:\"green\",shape:\"ring\",text:\"address-set-error\"});\n return error;\n}\n\n",
"outputs": 1,
"noerr": 0,
"x": 840,
"y": 100,
"wires": [
[]
]
},
{
"id": "a792f83e.20bed8",
"type": "switch",
"z": "7c29baf0.0afbdc",
"name": "",
"property": "service.currentIotaAddress",
"propertyType": "msg",
"rules": [
{
"t": "empty"
},
{
"t": "nempty"
}
],
"checkall": "true",
"repair": false,
"outputs": 2,
"x": 430,
"y": 140,
"wires": [
[
"c298808a.1f2ec8"
],
[]
]
},
{
"id": "4fc61f50.483b98",
"type": "status",
"z": "7c29baf0.0afbdc",
"name": "",
"scope": null,
"x": 800,
"y": 40,
"wires": [
[]
]
},
{
"id": "76b7192.e6e5de8",
"type": "subflow",
"name": "get-new-address",
"info": "",
"category": "iota",
"in": [
{
"x": 100,
"y": 100,
"wires": [
{
"id": "b76702d4.6468a"
}
]
}
],
"out": [
{
"x": 720,
"y": 100,
"wires": [
{
"id": "9654c7d8.58a26",
"port": 0
}
]
}
],
"env": [
{
"name": "IOTA_SEED",
"type": "env",
"value": "IOTA_SEED"
},
{
"name": "IOTA_ADDRESS_INDEX",
"type": "num",
"value": ""
},
{
"name": "IOTA_ADDRESS_SECURITY",
"type": "num",
"value": ""
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"status": {
"x": 720,
"y": 40,
"wires": [
{
"id": "de20b342.d6e2f",
"port": 0
}
]
}
},
{
"id": "9654c7d8.58a26",
"type": "function",
"z": "76b7192.e6e5de8",
"name": "create-address",
"func": "try {\n if (!msg || !msg.payload) throw new Error(\"No IOTA dependencies found\");\n const iota = msg.payload[\"iota-api\"];\n if (!iota || iota === null) throw new Error(\"Cannot get IOTA API instance\");\n const debug = env.get(\"debug\");\n const seed = env.get(\"IOTA_SEED\");\n \n const index = msg.addressIndex || env.get(\"IOTA_ADDRESS_INDEX\") || 1;\n const security = msg.addressSecurity || env.get(\"IOTA_ADDRESS_SECURITY\") || 1;\n iota.getNewAddress(seed, {index, security}, (err, res) => {\n if (err) throw err;\n msg.address = res;\n if (debug) {\n console.log(`Address created: ${res}`);\n }\n node.status({fill:\"green\",shape:\"ring\",text:\"address-create\"});\n node.send(msg);\n });\n \n} catch(error) {\n node.status({fill:\"red\",shape:\"ring\",text:\"address-create-error\"});\n // console.log(\"create address:err\", error);\n // node.error(\"Iota Error:\", error);\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 520,
"y": 100,
"wires": [
[]
]
},
{
"id": "b76702d4.6468a",
"type": "subflow:bbb4a70e.34bed8",
"z": "76b7192.e6e5de8",
"name": "",
"env": [
{
"name": "modules",
"type": "json",
"value": "[\"iota-api\"]"
}
],
"x": 260,
"y": 100,
"wires": [
[
"9654c7d8.58a26"
]
]
},
{
"id": "de20b342.d6e2f",
"type": "status",
"z": "76b7192.e6e5de8",
"name": "",
"scope": null,
"x": 540,
"y": 40,
"wires": [
[]
]
},
{
"id": "1a860746.f31d19",
"type": "subflow",
"name": "replace-device-iota-address",
"info": "",
"category": "iota",
"in": [
{
"x": 120,
"y": 120,
"wires": [
{
"id": "8ae77399.47c2c"
}
]
}
],
"out": [
{
"x": 940,
"y": 120,
"wires": [
{
"id": "db275a6c.a142e8",
"port": 0
}
]
}
],
"env": [
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "IOTA_SEED",
"type": "env",
"value": "IOTA_SEED"
}
]
},
{
"id": "3776749.4a7008c",
"type": "subflow:76b7192.e6e5de8",
"z": "1a860746.f31d19",
"name": "",
"env": [
{
"name": "IOTA_ADDRESS_SECURITY",
"type": "num",
"value": "2"
}
],
"x": 540,
"y": 120,
"wires": [
[
"db275a6c.a142e8"
]
]
},
{
"id": "8ae77399.47c2c",
"type": "function",
"z": "1a860746.f31d19",
"name": "set-iota-address-index",
"func": "\ntry {\n if (!msg.addressIndex || msg.addressIndex === null) {\n const d = new Date();\n msg.addressIndex = d.getTime();\n flow.set(\"iota-addres-index\", msg.addressIndex);\n }\n msg.addressSecurity = 1;\n console.log(\"replacing address with :\", {index: msg.addressIndex, security: msg.addressSecurity})\n return [msg, null];\n} catch(error) {\n return error;\n}",
"outputs": 2,
"noerr": 0,
"x": 300,
"y": 120,
"wires": [
[],
[]
]
},
{
"id": "db275a6c.a142e8",
"type": "function",
"z": "1a860746.f31d19",
"name": "set-iota-address",
"func": "\ntry {\n if (!msg || !msg.address || msg.address === null) throw new Error(\"no address to save\");\n global.set(`iota-address-${env.get('device_name')}`, msg.address, 'file', err => {\n if (err) throw err;\n });\n msg.payload = msg.address;\n return msg;\n} catch(error) {\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 780,
"y": 120,
"wires": [
[]
]
},
{
"id": "aacf35e9.4171b8",
"type": "comment",
"z": "1a860746.f31d19",
"name": "todo transfer funds before address generation ?",
"info": "",
"x": 440,
"y": 220,
"wires": []
},
{
"id": "7eb48b6.61cbbf4",
"type": "subflow",
"name": "check-transactions",
"info": "",
"category": "iota",
"in": [
{
"x": 200,
"y": 180,
"wires": [
{
"id": "b8da5f6e.29afa"
}
]
}
],
"out": [
{
"x": 740,
"y": 140,
"wires": [
{
"id": "b8da5f6e.29afa",
"port": 0
}
]
},
{
"x": 740,
"y": 220,
"wires": [
{
"id": "b8da5f6e.29afa",
"port": 1
}
]
}
],
"env": [
{
"name": "store_type",
"type": "str",
"value": "file"
},
{
"name": "device_id",
"type": "str",
"value": ""
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"outputLabels": [
"on-update",
"interface"
],
"status": {
"x": 740,
"y": 80,
"wires": [
{
"id": "aac67840.238968",
"port": 0
}
]
}
},
{
"id": "b8da5f6e.29afa",
"type": "function",
"z": "7eb48b6.61cbbf4",
"name": "check-iota-transactions",
"func": "const debug = env.get(\"debug\");\n\nconst checkBalance = (service) => {\n try {\n let iotaPrice = global.get(\"iota-price-dollar\");\n \n if (service.currentIotaBalance > 0) {\n if (debug) {\n console.log(\"iotaPrice :\", iotaPrice);\n console.log(\"iotaBalance :\", service.currentIotaBalance);\n }\n if (service.currentIotaBalance > service.lastIotaBalance) {\n const addedBalance = (service.currentIotaBalance / iotaPrice - service.lastIotaBalance / iotaPrice);\n if (debug) {\n console.log(\"serviceBalance adding :\", addedBalance);\n }\n service.currentBalance += addedBalance;\n service.currentBalance = Number(service.currentBalance.toFixed(4));\n service.lastIotaBalance = service.currentIotaBalance;\n return true; \n }\n }\n service.lastIotaBalance = service.currentIotaBalance;\n return false;\n } catch(error) {\n if (debug) {\n console.log(\"checkBalance:err :\", error);\n }\n return false;\n }\n}\n\nconst checkTransactions = (service, transactions) => {\n try {\n // console.log(\"transactionsCount :\", service.transactionsCount);\n if (transactions.length > service.transactionsCount) {\n service.transactionsCount = transactions.length;\n if (debug) {\n console.log(\"transactionUpdate :\", service.transactionsCount);\n }\n return true;\n }\n return false;\n } catch(error) {\n if (debug) {\n console.log(\"checkTransactions:err :\", error);\n }\n return false;\n }\n}\n\n\ntry {\n let transactions = msg.transactions;\n if (!transactions || transactions === null || transactions.length < 1) return null;\n const storeType = env.get(\"store_type\");\n const deviceId = env.get('device_id');\n if (!deviceId || deviceId === null) throw new Error(\"Missing device Id\");\n \n let service;\n global.get(`service-${deviceId}`, storeType, (err, res) => {\n if (err) throw err;\n service = res || null; \n });\n if (!service || service === null) throw new Error(\"No service found\");\n\n\n const transactionUpdated = checkTransactions(service, transactions);\n const balanceUpdated = checkBalance(service);\n if (debug) {\n console.log(\"balanceUpdated ?\", balanceUpdated);\n console.log(\"transactionUpdated ?\", transactionUpdated);\n }\n\n global.set(`service-${deviceId}`, service, storeType, (err) => {\n if (err) throw err;\n });\n msg.service = service;\n \n if (balanceUpdated && transactionUpdated) {\n // const d = new Date();\n // msg.addressIndex = d.getTime();\n // flow.set(\"iota-addres-index\", msg.addressIndex);\n msg.label = 'Transaction done';\n node.status({fill:\"green\",shape:\"ring\",text:\"transaction-update\"});\n return [msg, msg];\n }\n if (transactionUpdated && !balanceUpdated) {\n // const d = new Date();\n // msg.addressIndex = d.getTime();\n msg.label = 'Transaction ongoing';\n node.status({fill:\"yellow\",shape:\"ring\",text:\"transaction-in-progress\"});\n return [null, msg];\n }\n if (!transactionUpdated && balanceUpdated) {\n msg.label = 'Transaction done';\n node.status({fill:\"green\",shape:\"ring\",text:\"transaction-update\"});\n return [msg, msg];\n }\n return [null, null];\n} catch(error) {\n node.status({fill:\"red\",shape:\"ring\",text:\"transaction-update-error\"});\n return error;\n}\n\n\n",
"outputs": 2,
"noerr": 0,
"x": 470,
"y": 180,
"wires": [
[],
[]
]
},
{
"id": "aac67840.238968",
"type": "status",
"z": "7eb48b6.61cbbf4",
"name": "",
"scope": null,
"x": 420,
"y": 80,
"wires": [
[]
]
},
{
"id": "4112cf6c.f8ca7",
"type": "subflow",
"name": "generate-qrcode",
"info": "",
"category": "",
"in": [
{
"x": 180,
"y": 180,
"wires": [
{
"id": "717e80dc.86f15"
}
]
}
],
"out": [
{
"x": 740,
"y": 180,
"wires": [
{
"id": "c63e7ca2.98ac78",
"port": 0
}
]
}
],
"env": [
{
"name": "output",
"type": "str",
"value": "file"
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
]
},
{
"id": "717e80dc.86f15",
"type": "change",
"z": "4112cf6c.f8ca7",
"name": "qrcode",
"rules": [
{
"t": "set",
"p": "qrcode",
"pt": "msg",
"to": "qrcode",
"tot": "global"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 300,
"y": 180,
"wires": [
[
"c63e7ca2.98ac78"
]
]
},
{
"id": "c63e7ca2.98ac78",
"type": "function",
"z": "4112cf6c.f8ca7",
"name": "qrcode-data-url",
"func": "if (!msg || !msg.qrcode || msg.qrcode === null) return null;\nif (!msg.payload || msg.payload === null) return null;\n\nmsg.qrcode.toDataURL(msg.payload, { errorCorrectionLevel: 'M' })\n .then(url => {\n if (env.get(\"debug\")) {\n console.log(\"qr-code-data-url :\", url);\n }\n msg.qrCodeAddress = url;\n node.send(msg);\n })\n .catch(err => {\n console.error(err)\n })\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 530,
"y": 180,
"wires": [
[]
]
},
{
"id": "1ec992e9.958055",
"type": "function",
"z": "4112cf6c.f8ca7",
"name": "qrcode-file",
"func": "if (!msg || !msg.qrcode || msg.qrcode === null) return null;\nif (!msg.payload || msg.payload === null) return null;\n\ntry {\n const path = env.get(\"path\");\n if (!path) return null;\n msg.qrcode.toFile(path, msg.payload, {type: 'png', errorCorrectionLevel: 'M' }, err => {\n if (err) throw err;\n node.send(msg);\n })\n return msg; \n} catch(error) {\n return error;\n}\n ",
"outputs": 1,
"noerr": 0,
"x": 510,
"y": 240,
"wires": [
[]
]
},
{
"id": "e30ce4bf.a549b8",
"type": "subflow",
"name": "get-address-transactions",
"info": "",
"category": "iota",
"in": [
{
"x": 100,
"y": 140,
"wires": [
{
"id": "bbb59b67.c69b3"
}
]
}
],
"out": [
{
"x": 720,
"y": 140,
"wires": [
{
"id": "c70404f1.e9af",
"port": 0
}
]
}
],
"env": [
{
"name": "address",
"type": "str",
"value": ""
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"status": {
"x": 720,
"y": 60,
"wires": [
{
"id": "f5e336e5.fb783",
"port": 0
}
]
}
},
{
"id": "bbb59b67.c69b3",
"type": "subflow:bbb4a70e.34bed8",
"z": "e30ce4bf.a549b8",
"name": "",
"env": [
{
"name": "modules",
"type": "json",
"value": "[\"iota-api\"]"
}
],
"x": 270,
"y": 140,
"wires": [
[
"c70404f1.e9af"
]
]
},
{
"id": "c70404f1.e9af",
"type": "function",
"z": "e30ce4bf.a549b8",
"name": "get-address-transactions",
"func": "try {\n if (!msg || !msg.payload) throw new Error(\"No IOTA dependencies found\");\n const iota = msg.payload[\"iota-api\"];\n if (!iota || iota === null) throw new Error(\"Cannot get IOTA API\");\n\n const address = msg.address || env.get(\"address\");\n if (!address || address === null) throw new Error(\"Empty address\");\n const addresses = [address];\n if (env.get(\"debug\")) {\n console.log(\"address transactions req: \", address);\n }\n \n iota.findTransactions({addresses}, (err, res) => {\n if (err) throw err;\n if (env.get(\"debug\")) {\n console.log(\"address transactions: \", res);\n }\n msg.transactions = res;\n node.send(msg);\n node.status({fill:\"green\",shape:\"ring\",text:\"transactions-get\"});\n });\n\n} catch(error) {\n node.status({fill:\"red\",shape:\"ring\",text:\"transactions-get-error\"});\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 510,
"y": 140,
"wires": [
[]
]
},
{
"id": "f5e336e5.fb783",
"type": "status",
"z": "e30ce4bf.a549b8",
"name": "",
"scope": null,
"x": 460,
"y": 60,
"wires": [
[]
]
},
{
"id": "bbb4a70e.34bed8",
"type": "subflow",
"name": "get-IOTA-modules",
"info": "",
"category": "iota",
"in": [
{
"x": 140,
"y": 160,
"wires": [
{
"id": "2b2d4a34.fcdf56"
}
]
}
],
"out": [
{
"x": 1120,
"y": 120,
"wires": [
{
"id": "592d579a.e2176",
"port": 0
}
]
}
],
"env": [
{
"name": "modules",
"type": "json",
"value": "[\"iota-core\",\"iota-converter\"]"
}
],
"status": {
"x": 1120,
"y": 40,
"wires": [
{
"id": "68c8e66c.86d1b8",
"port": 0
}
]
}
},
{
"id": "2b2d4a34.fcdf56",
"type": "function",
"z": "bbb4a70e.34bed8",
"name": "get-iota-dependencies",
"func": "try {\n const modules = env.get(\"modules\");\n if (!modules || modules === null) return null;\n modules.forEach((module, index) => {\n msg.payload = module;\n if (index === modules.length - 1) {\n msg.complete = true;\n node.status({fill:'green', shape:'ring', text: 'iota-module-get'});\n node.send(msg);\n } else {\n node.send(msg);\n node.status({fill:'yellow', shape:'ring', text: 'iota-module-get'});\n }\n return null;\n });\n \n} catch(error) {\n node.status({fill:'red', shape:'ring', text: 'iota-module-get-error'});\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 300,
"y": 160,
"wires": [
[
"f19f1218.5fc69"
]
]
},
{
"id": "f19f1218.5fc69",
"type": "switch",
"z": "bbb4a70e.34bed8",
"name": "",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "iota-api",
"vt": "str"
},
{
"t": "eq",
"v": "iota-converter",
"vt": "str"
},
{
"t": "eq",
"v": "iota-extract-json",
"vt": "str"
},
{
"t": "eq",
"v": "iota-mam",
"vt": "str"
},
{
"t": "eq",
"v": "iota-signing",
"vt": "str"
},
{
"t": "eq",
"v": "iota-transaction-converter",
"vt": "str"
},
{
"t": "else"
}
],
"checkall": "false",
"repair": false,
"outputs": 7,
"x": 490,
"y": 160,
"wires": [
[
"fd1791ea.2ebe78"
],
[
"d64e2a.9f72d1d8"
],
[
"e31aa374.c23f7"
],
[
"67cafff0.632b38"
],
[
"4d2eeaf4.787c84"
],
[
"ff1b3978.9e5cb8"
],
[]
]
},
{
"id": "592d579a.e2176",
"type": "join",
"z": "bbb4a70e.34bed8",
"name": "",
"mode": "custom",
"build": "object",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"accumulate": false,
"timeout": "",
"count": "",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 1010,
"y": 120,
"wires": [
[]
]
},
{
"id": "fd1791ea.2ebe78",
"type": "change",
"z": "bbb4a70e.34bed8",
"name": "iota-api",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "iota-api",
"tot": "global"
},
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "iota-api",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 740,
"y": 80,
"wires": [
[
"592d579a.e2176"
]
]
},
{
"id": "d64e2a.9f72d1d8",
"type": "change",
"z": "bbb4a70e.34bed8",
"name": "iota-converter",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "iota-converter",
"tot": "global"
},
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "iota-converter",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 760,
"y": 120,
"wires": [
[
"592d579a.e2176"
]
]
},
{
"id": "4d2eeaf4.787c84",
"type": "change",
"z": "bbb4a70e.34bed8",
"name": "iota-signing",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "iota-signing",
"tot": "global"
},
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "iota-signing",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 750,
"y": 240,
"wires": [
[
"592d579a.e2176"
]
]
},
{
"id": "67cafff0.632b38",
"type": "change",
"z": "bbb4a70e.34bed8",
"name": "iota-mam",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "iota-mam",
"tot": "global"
},
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "iota-mam",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 740,
"y": 200,
"wires": [
[
"592d579a.e2176"
]
]
},
{
"id": "68c8e66c.86d1b8",
"type": "status",
"z": "bbb4a70e.34bed8",
"name": "",
"scope": [
"2b2d4a34.fcdf56"
],
"x": 940,
"y": 40,
"wires": [
[]
]
},
{
"id": "ff1b3978.9e5cb8",
"type": "change",
"z": "bbb4a70e.34bed8",
"name": "iota-transaction-converter",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "iota-transaction-converter",
"tot": "global"
},
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "iota-transaction-converter",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 790,
"y": 280,
"wires": [
[
"592d579a.e2176"
]
]
},
{
"id": "e31aa374.c23f7",
"type": "change",
"z": "bbb4a70e.34bed8",
"name": "iota-extract-json",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "iota-extract-json",
"tot": "global"
},
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "iota-extract-json",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 760,
"y": 160,
"wires": [
[
"592d579a.e2176"
]
]
},
{
"id": "ad464c7c.2e71e8",
"type": "subflow",
"name": "get-address-balance",
"info": "",
"category": "iota",
"in": [
{
"x": 140,
"y": 140,
"wires": [
{
"id": "9e80fc15.818d08"
}
]
}
],
"out": [
{
"x": 740,
"y": 140,
"wires": [
{
"id": "545b9ec7.21c3a8",
"port": 0
}
]
}
],
"env": [
{
"name": "address",
"type": "str",
"value": ""
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"status": {
"x": 740,
"y": 60,
"wires": [
{
"id": "54bc1eeb.982378",
"port": 0
}
]
}
},
{
"id": "9e80fc15.818d08",
"type": "subflow:bbb4a70e.34bed8",
"z": "ad464c7c.2e71e8",
"name": "",
"env": [
{
"name": "modules",
"type": "json",
"value": "[\"iota-api\"]"
}
],
"x": 310,
"y": 140,
"wires": [
[
"545b9ec7.21c3a8"
]
]
},
{
"id": "545b9ec7.21c3a8",
"type": "function",
"z": "ad464c7c.2e71e8",
"name": "get-address-balance",
"func": "try {\n if (!msg || !msg.payload) throw new Error(\"No IOTA dependencies found\");\n const iota = msg.payload[\"iota-api\"];\n if (!iota || iota === null) throw new Error(\"Cannot get IOTA API\");\n\n const address = msg.address || env.get(\"address\");\n if (!address || address === null) throw new Error(\"Empty address\");\n const addresses = [address];\n \n iota.getBalances(addresses, 100, (err, res) => {\n if (err) throw err;\n if (env.get(\"debug\")) {\n console.log(\"device balances: \", res);\n }\n msg.balance = res;\n node.send(msg);\n node.status({fill:\"green\",shape:\"ring\",text:\"balance-get\"});\n });\n\n} catch(error) {\n node.status({fill:\"red\",shape:\"ring\",text:\"balance-get-error\"});\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 560,
"y": 140,
"wires": [
[]
]
},
{
"id": "54bc1eeb.982378",
"type": "status",
"z": "ad464c7c.2e71e8",
"name": "",
"scope": null,
"x": 320,
"y": 60,
"wires": [
[]
]
},
{
"id": "2cff5c49.cc97e4",
"type": "subflow",
"name": "check-iota-state",
"info": "",
"category": "iota",
"in": [
{
"x": 80,
"y": 160,
"wires": [
{
"id": "3468fde.f9da802"
}
]
}
],
"out": [
{
"x": 1100,
"y": 160,
"wires": [
{
"id": "df689d84.a44f4",
"port": 0
}
]
},
{
"x": 1100,
"y": 260,
"wires": [
{
"id": "110a0c50.70cb3c",
"port": 1
}
]
},
{
"x": 1100,
"y": 360,
"wires": [
{
"id": "dd3de597.fea798",
"port": 0
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "device_id",
"type": "env",
"value": "device_id"
},
{
"name": "store_type",
"type": "str",
"value": "file"
}
],
"outputLabels": [
"balance",
"transactions",
"address-qrcode"
],
"status": {
"x": 1100,
"y": 60,
"wires": [
{
"id": "7a13ccd4.831374",
"port": 0
}
]
}
},
{
"id": "3468fde.f9da802",
"type": "function",
"z": "2cff5c49.cc97e4",
"name": "get-iota-address",
"func": "try {\n const storeType = env.get('store_type');\n if (!msg) throw new Error(\"Empty message\");\n const debug = env.get(\"debug\");\n const deviceId = env.get(\"device_id\");\n if (!deviceId || deviceId === null) throw new Error(\"Missing device_id\");\n \n global.get(`service-${deviceId}`, storeType, (err, res) => {\n if (err) throw err;\n msg.service = res || null; \n });\n\n if (!msg.service || msg.service === null) throw new Error(\"No Service initialized yet\");\n msg.address = msg.payload = msg.service.currentIotaAddress;\n if (debug) {\n console.log(\"Retrieved Address\", msg.address);\n }\n node.status({fill:\"green\",shape:\"ring\",text:\"address-get\"});\n return msg;\n} catch(error) {\n node.status({fill:\"red\",shape:\"ring\",text:\"address-get-error\"});\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 250,
"y": 160,
"wires": [
[
"43e5a125.ba9c88",
"529d9679.168718",
"dd3de597.fea798"
]
]
},
{
"id": "43e5a125.ba9c88",
"type": "subflow:ad464c7c.2e71e8",
"z": "2cff5c49.cc97e4",
"name": "",
"env": [
{
"name": "debug",
"type": "env",
"value": "debug"
}
],
"x": 520,
"y": 160,
"wires": [
[
"df689d84.a44f4"
]
]
},
{
"id": "529d9679.168718",
"type": "subflow:e30ce4bf.a549b8",
"z": "2cff5c49.cc97e4",
"name": "",
"env": [
{
"name": "debug",
"type": "env",
"value": "debug"
}
],
"x": 530,
"y": 260,
"wires": [
[
"110a0c50.70cb3c"
]
]
},
{
"id": "dd3de597.fea798",
"type": "subflow:4112cf6c.f8ca7",
"z": "2cff5c49.cc97e4",
"name": "",
"env": [
{
"name": "output",
"type": "str",
"value": "dataurl"
},
{
"name": "debug",
"type": "env",
"value": "debug"
}
],
"x": 500,
"y": 360,
"wires": [
[]
]
},
{
"id": "df689d84.a44f4",
"type": "function",
"z": "2cff5c49.cc97e4",
"name": "set-balance",
"func": "const debug = env.get(\"debug\");\n\nconst setBalance = (balance, deviceId, storeType, cb) => {\n try {\n let service;\n global.get(`service-${deviceId}`, storeType, (err, res) => {\n if (err) throw err;\n service = res || null; \n });\n if (!service || service === null) return [null, null];\n service.currentIotaBalance = balance;\n global.set(`service-${deviceId}`, service, storeType, (err) => {\n if (err) throw err;\n });\n return cb(null,service);\n } catch(error) {\n return cb(error, null);\n }\n}\n\ntry {\n const storeType = env.get('store_type');\n const deviceId = env.get('device_id');\n if (!deviceId || deviceId === null) throw new Error(\"Missing device Id\");\n if (!msg || !msg.balance || !msg.balance.balances ) throw new Error(\"Missing balance\");\n let balance = msg.balance.balances[0];\n\n setBalance(balance, deviceId, storeType, (err,res) => {\n if (err) throw err;\n if (debug) {\n console.log(\"setBalance:res\", res);\n }\n if (res && !(res instanceof Error) ) {\n msg.service = res;\n node.status({fill:\"green\",shape:\"ring\",text:\"balance-set\"});\n node.send(msg);\n } \n });\n return null;\n} catch(error) {\n node.status({fill:\"red\",shape:\"ring\",text:\"balance-set-error\"});\n return error;\n}\n\n\n",
"outputs": 1,
"noerr": 0,
"x": 770,
"y": 160,
"wires": [
[]
]
},
{
"id": "110a0c50.70cb3c",
"type": "subflow:7eb48b6.61cbbf4",
"z": "2cff5c49.cc97e4",
"name": "",
"env": [
{
"name": "device_id",
"type": "env",
"value": "device_id"
}
],
"x": 790,
"y": 260,
"wires": [
[],
[]
]
},
{
"id": "30c488bf.d72958",
"type": "subflow:1a860746.f31d19",
"z": "2cff5c49.cc97e4",
"name": "",
"env": [],
"x": 860,
"y": 220,
"wires": [
[]
]
},
{
"id": "7a13ccd4.831374",
"type": "status",
"z": "2cff5c49.cc97e4",
"name": "",
"scope": null,
"x": 500,
"y": 60,
"wires": [
[]
]
},
{
"id": "d7a593e6.9b06f",
"type": "subflow",
"name": "relay-3",
"info": "",
"category": "relays",
"in": [
{
"x": 120,
"y": 200,
"wires": [
{
"id": "a2c13dd5.ad04e8"
}
]
}
],
"out": [
{
"x": 1120,
"y": 160,
"wires": [
{
"id": "415eb58d.66a464",
"port": 0
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
},
{
"name": "device_id",
"type": "str",
"value": ""
},
{
"name": "device_name",
"type": "str",
"value": ""
},
{
"name": "user_id",
"type": "env",
"value": "ALOES_USER_ID"
},
{
"name": "store_type",
"type": "env",
"value": "NODE_RED_STORE_TYPE"
}
],
"icon": "font-awesome/fa-desktop",
"status": {
"x": 1120,
"y": 220,
"wires": [
{
"id": "6b98adbf.fda044",
"port": 0
}
]
}
},
{
"id": "66a5d17f.51e3c",
"type": "comment",
"z": "d7a593e6.9b06f",
"name": "Device properties",
"info": "",
"x": 190,
"y": 480,
"wires": []
},
{
"id": "bf2f0a2d.1557a",
"type": "ui_switch",
"z": "d7a593e6.9b06f",
"name": "relay-3-selection",
"label": "{{msg.label}}",
"tooltip": "{{msg.tooltip}}",
"group": "18dbcafd.0bd0d5",
"order": 4,
"width": "3",
"height": "1",
"passthru": false,
"decouple": "true",
"topic": "",
"style": "",
"onvalue": "true",
"onvalueType": "bool",
"onicon": "",
"oncolor": "",
"offvalue": "false",
"offvalueType": "bool",
"officon": "",
"offcolor": "",
"x": 950,
"y": 540,
"wires": [
[
"6e23dc64.7fe784"
]
]
},
{
"id": "1769f6f6.6238a9",
"type": "ui_template",
"z": "d7a593e6.9b06f",
"group": "18dbcafd.0bd0d5",
"name": "relay-3-status",
"order": 3,
"width": "6",
"height": "1",
"format": "<!DOCTYPE html>\n<svg viewBox=\"0 0 270 40\" id=\"{{'devices-status-'+ $id}}\">\n <text x=\"0\" y=\"25\" style=\"{{'font-weight:700'}}\" >{{$deviceName}}</text>\n <image\n id=\"{{'device-icon-'+$id}}\" \n x=\"200\"\n y=\"2\"\n width=\"35px\" \n height=\"35px\"\n preserveAspectRatio=\"xMidYMin slice\"\n xlink:href=\"{{ $getImageUrl() }}\"></image>\n <circle id=\"{{'devices-status-icon-'+$id}}\" x=\"0\" y=\"0\" cx=\"265\" cy=\"20\" r=\"15\" fill=\"{{$statusColor}}\" ></circle>\n</svg>\n<script>\n(function(scope) {\n scope.$watch('msg', (msg) => {\n try{\n scope.$statusText = \"Waiting\";\n scope.$deviceName = \"\";\n scope.$statusColor = \"#ff4500\";\n scope.$getImageUrl = () => {\n const icon = scope.$deviceIcon || \"\";\n return icon;\n }\n if (msg && msg.device) {\n scope.$deviceName = msg.device.name;\n scope.$deviceIcon = msg.device.icons[0];\n if (msg && (msg.device.status === true || msg.device.status === \"true\")) {\n scope.$statusColor = \"#baff00\";\n scope.$statusText = \"Ready\";\n }\n }\n // return msg;\n } catch(error){\n return error;\n }\n \n });\n})(scope);\n</script>",
"storeOutMessages": false,
"fwdInMessages": false,
"templateScope": "local",
"x": 320,
"y": 580,
"wires": [
[]
]
},
{
"id": "6e23dc64.7fe784",
"type": "subflow:32f8e46a.971f8c",
"z": "d7a593e6.9b06f",
"name": "",
"env": [
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "store_type",
"type": "str",
"value": "file"
}
],
"x": 1180,
"y": 540,
"wires": [
[
"82b01d42.ab4e38"
]
]
},
{
"id": "dbe6c933.a56ef",
"type": "change",
"z": "d7a593e6.9b06f",
"name": "devicesSelection",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "#:(file)::devicesSelection",
"tot": "global"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 330,
"y": 540,
"wires": [
[
"3d07441b.a05e0c"
]
]
},
{
"id": "82b01d42.ab4e38",
"type": "subflow:8ff67ce6.9014f",
"z": "d7a593e6.9b06f",
"name": "",
"env": [
{
"name": "label_true",
"type": "str",
"value": "Remove"
},
{
"name": "tooltip_true",
"type": "str",
"value": "Remove from device selection"
},
{
"name": "topic_true",
"type": "str",
"value": "DELETE/devicesSelection"
},
{
"name": "payload_true",
"type": "bool",
"value": "true"
},
{
"name": "label_false",
"type": "str",
"value": "Add"
},
{
"name": "tooltip_false",
"type": "str",
"value": "Add to device selection"
},
{
"name": "topic_false",
"type": "str",
"value": "POST/devicesSelection"
},
{
"name": "payload_false",
"type": "bool",
"value": "false"
}
],
"x": 740,
"y": 540,
"wires": [
[
"bf2f0a2d.1557a"
]
]
},
{
"id": "a4a0918.86e927",
"type": "link in",
"z": "d7a593e6.9b06f",
"name": "->device-properties",
"links": [
"7e6a93b7.0ee08c"
],
"x": 115,
"y": 540,
"wires": [
[
"dbe6c933.a56ef",
"1769f6f6.6238a9",
"8dd4df06.c0e0c8"
]
]
},
{
"id": "2472da70.02092e",
"type": "subflow:2188cc9a.23fde4",
"z": "d7a593e6.9b06f",
"name": "",
"env": [
{
"name": "store_type",
"type": "env",
"value": "store_type"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
}
],
"x": 960,
"y": 1020,
"wires": [
[
"700e6837.955b18"
]
]
},
{
"id": "68992b55.a8ba54",
"type": "link in",
"z": "d7a593e6.9b06f",
"name": "SWITCH/3306/1/5850",
"links": [
"e6d69a48.829dd8",
"2566aa1a.c7b2c6"
],
"x": 95,
"y": 920,
"wires": [
[
"9679301d.2633b8"
]
]
},
{
"id": "fed364b7.5c7ab8",
"type": "link in",
"z": "d7a593e6.9b06f",
"name": "SWITCH/3306/2/5850",
"links": [],
"x": 95,
"y": 1040,
"wires": [
[]
]
},
{
"id": "e26364b9.a5bb4",
"type": "link in",
"z": "d7a593e6.9b06f",
"name": "",
"links": [
"9fc73512.d00b28",
"5078abd3.833454"
],
"x": 95,
"y": 1100,
"wires": [
[
"fca16a95.009378"
]
]
},
{
"id": "4887c82e.d1535",
"type": "link in",
"z": "d7a593e6.9b06f",
"name": "",
"links": [],
"x": 95,
"y": 1180,
"wires": [
[]
]
},
{
"id": "cd47433.ed3aec",
"type": "ui_switch",
"z": "d7a593e6.9b06f",
"name": "PUT/sensor/3306/1/5850",
"label": "switch",
"tooltip": "Turn on/off relay",
"group": "be53547b.4765a8",
"order": 2,
"width": "6",
"height": "1",
"passthru": false,
"decouple": "false",
"topic": "",
"style": "",
"onvalue": "true",
"onvalueType": "bool",
"onicon": "",
"oncolor": "",
"offvalue": "false",
"offvalueType": "bool",
"officon": "",
"offcolor": "",
"x": 450,
"y": 920,
"wires": [
[
"acdbf183.1d4658",
"ccb8689c.1540a8"
]
]
},
{
"id": "bde92e03.72493",
"type": "subflow:f8bab707.28f4c",
"z": "d7a593e6.9b06f",
"name": "",
"env": [
{
"name": "resource_id",
"type": "str",
"value": "5850"
},
{
"name": "precision",
"type": "num",
"value": "1"
}
],
"x": 300,
"y": 980,
"wires": [
[
"ccb8689c.1540a8"
]
]
},
{
"id": "ccb8689c.1540a8",
"type": "ui_chart",
"z": "d7a593e6.9b06f",
"name": "",
"group": "be53547b.4765a8",
"order": 4,
"width": "12",
"height": "7",
"label": "3306/1/5850",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "step",
"nodata": "",
"dot": false,
"ymin": "0",
"ymax": "1",
"removeOlder": 1,
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"useOldStyle": false,
"outputs": 1,
"x": 470,
"y": 980,
"wires": [
[]
]
},
{
"id": "13526833.60e778",
"type": "comment",
"z": "d7a593e6.9b06f",
"name": "Sensor properties",
"info": "",
"x": 170,
"y": 860,
"wires": []
},
{
"id": "d801357d.5811a",
"type": "ui_slider",
"z": "d7a593e6.9b06f",
"name": "PUT/sensor/3306/1/5851",
"label": "slider",
"tooltip": "",
"group": "be53547b.4765a8",
"order": 3,
"width": "6",
"height": "1",
"passthru": false,
"outs": "end",
"topic": "",
"min": 0,
"max": "100",
"step": 1,
"x": 450,
"y": 1100,
"wires": [
[
"57caff62.0a054"
]
]
},
{
"id": "fca16a95.009378",
"type": "subflow:f8bab707.28f4c",
"z": "d7a593e6.9b06f",
"name": "",
"env": [
{
"name": "resource_id",
"type": "str",
"value": "5851"
},
{
"name": "precision",
"type": "num",
"value": "1"
},
{
"name": "unit",
"type": "str",
"value": "%"
}
],
"x": 200,
"y": 1100,
"wires": [
[
"d801357d.5811a"
]
]
},
{
"id": "700e6837.955b18",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "updated-instance->",
"links": [
"415eb58d.66a464"
],
"x": 1115,
"y": 1020,
"wires": []
},
{
"id": "acdbf183.1d4658",
"type": "subflow:de56f8d.072c908",
"z": "d7a593e6.9b06f",
"name": "",
"env": [
{
"name": "method",
"type": "str",
"value": "PUT"
},
{
"name": "object_id",
"type": "str",
"value": "3306"
},
{
"name": "resource_id",
"type": "str",
"value": "5850"
}
],
"x": 680,
"y": 920,
"wires": [
[
"2472da70.02092e"
]
]
},
{
"id": "57caff62.0a054",
"type": "subflow:de56f8d.072c908",
"z": "d7a593e6.9b06f",
"name": "",
"env": [
{
"name": "method",
"type": "str",
"value": "PUT"
},
{
"name": "object_id",
"type": "str",
"value": "3306"
},
{
"name": "resource_id",
"type": "str",
"value": "5851"
}
],
"x": 695,
"y": 1100,
"wires": [
[
"2472da70.02092e"
]
]
},
{
"id": "9679301d.2633b8",
"type": "subflow:1e071b74.a346dd",
"z": "d7a593e6.9b06f",
"name": "",
"env": [
{
"name": "resource_id",
"type": "str",
"value": "5850"
}
],
"x": 210,
"y": 920,
"wires": [
[
"cd47433.ed3aec",
"bde92e03.72493"
]
]
},
{
"id": "8f6d0bcc.3099c",
"type": "change",
"z": "d7a593e6.9b06f",
"name": "PUT/sensor/3306/1/5850",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "PUT/sensor/3306/1/5850",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 310,
"y": 1340,
"wires": [
[]
]
},
{
"id": "e9dd6dab.537ad8",
"type": "comment",
"z": "d7a593e6.9b06f",
"name": "Scenario",
"info": "",
"x": 160,
"y": 1280,
"wires": []
},
{
"id": "bd2a8afe.cab85",
"type": "link in",
"z": "d7a593e6.9b06f",
"name": "SWITCH/3306/1/5850",
"links": [
"e6d69a48.829dd8"
],
"x": 115,
"y": 1340,
"wires": [
[
"8f6d0bcc.3099c"
]
]
},
{
"id": "7e6a93b7.0ee08c",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "device-properties->",
"links": [
"a4a0918.86e927"
],
"x": 395,
"y": 60,
"wires": []
},
{
"id": "415eb58d.66a464",
"type": "link in",
"z": "d7a593e6.9b06f",
"name": "aloes-client->",
"links": [
"700e6837.955b18"
],
"x": 940,
"y": 160,
"wires": [
[]
]
},
{
"id": "e6d69a48.829dd8",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "1/3306/1/5850",
"links": [
"68992b55.a8ba54",
"bd2a8afe.cab85"
],
"x": 715,
"y": 100,
"wires": []
},
{
"id": "58c4ccea.b93d04",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "1/3306/2/5850",
"links": [],
"x": 715,
"y": 180,
"wires": []
},
{
"id": "9fc73512.d00b28",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "1/3306/1/5851",
"links": [
"e26364b9.a5bb4"
],
"x": 715,
"y": 260,
"wires": []
},
{
"id": "cfcd06a6.56f0a",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "1/3306/2/5851",
"links": [],
"x": 715,
"y": 340,
"wires": []
},
{
"id": "a2c13dd5.ad04e8",
"type": "subflow:541e2a83.f89d2c",
"z": "d7a593e6.9b06f",
"name": "",
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"x": 280,
"y": 200,
"wires": [
[
"7e6a93b7.0ee08c"
],
[
"ca2f5fd1.8d1828"
],
[
"dda19b74.70bea8"
],
[
"e9688d52.178b38"
],
[
"56ee204e.af8d88"
],
[
"352e5388.4409fc"
]
],
"info": "# relay-logic\n\n- Plug it after a aloes-client node\n- Set device_name and device id ( from your Aloes account)\n- Output whole device object and sensor properties \n"
},
{
"id": "2566aa1a.c7b2c6",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "0/3306/1/5850",
"links": [
"68992b55.a8ba54"
],
"x": 715,
"y": 140,
"wires": []
},
{
"id": "65f19674.80303",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "0/3306/2/5850",
"links": [],
"x": 715,
"y": 220,
"wires": []
},
{
"id": "5078abd3.833454",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "0/3306/1/5851",
"links": [
"e26364b9.a5bb4"
],
"x": 715,
"y": 300,
"wires": []
},
{
"id": "2d429f81.416d78",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "0/3306/2/5851",
"links": [],
"x": 715,
"y": 380,
"wires": []
},
{
"id": "e958d7c1.734f6",
"type": "comment",
"z": "d7a593e6.9b06f",
"name": "FLOW OUPUT",
"info": "",
"x": 1000,
"y": 60,
"wires": []
},
{
"id": "87cb9cb8.4c5c68",
"type": "comment",
"z": "d7a593e6.9b06f",
"name": "FLOW INPUT",
"info": "",
"x": 170,
"y": 60,
"wires": []
},
{
"id": "ca2f5fd1.8d1828",
"type": "switch",
"z": "d7a593e6.9b06f",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 500,
"y": 120,
"wires": [
[
"e6d69a48.829dd8"
],
[
"e6d69a48.829dd8"
],
[],
[
"2566aa1a.c7b2c6"
]
]
},
{
"id": "dda19b74.70bea8",
"type": "switch",
"z": "d7a593e6.9b06f",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 500,
"y": 200,
"wires": [
[
"58c4ccea.b93d04"
],
[
"58c4ccea.b93d04"
],
[],
[
"65f19674.80303"
]
]
},
{
"id": "e9688d52.178b38",
"type": "switch",
"z": "d7a593e6.9b06f",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 500,
"y": 280,
"wires": [
[
"9fc73512.d00b28"
],
[
"9fc73512.d00b28"
],
[],
[
"5078abd3.833454"
]
]
},
{
"id": "56ee204e.af8d88",
"type": "switch",
"z": "d7a593e6.9b06f",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 500,
"y": 360,
"wires": [
[
"cfcd06a6.56f0a"
],
[
"cfcd06a6.56f0a"
],
[],
[
"2d429f81.416d78"
]
]
},
{
"id": "8dd4df06.c0e0c8",
"type": "change",
"z": "d7a593e6.9b06f",
"name": "description",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "device.description",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 310,
"y": 620,
"wires": [
[
"6ff40a67.e221c4"
]
]
},
{
"id": "6ff40a67.e221c4",
"type": "ui_text",
"z": "d7a593e6.9b06f",
"group": "be53547b.4765a8",
"order": 1,
"width": "12",
"height": "1",
"name": "description",
"label": "",
"format": "{{msg.payload || \"\" }}",
"layout": "row-left",
"x": 490,
"y": 620,
"wires": []
},
{
"id": "3d07441b.a05e0c",
"type": "subflow:41c6c6f2.febed8",
"z": "d7a593e6.9b06f",
"name": "",
"env": [],
"x": 540,
"y": 540,
"wires": [
[
"82b01d42.ab4e38"
]
]
},
{
"id": "352e5388.4409fc",
"type": "link out",
"z": "d7a593e6.9b06f",
"name": "measurements->",
"links": [
"e70d791.6befc88"
],
"x": 395,
"y": 440,
"wires": []
},
{
"id": "e70d791.6befc88",
"type": "link in",
"z": "d7a593e6.9b06f",
"name": "iota-publish->",
"links": [
"352e5388.4409fc"
],
"x": 115,
"y": 1420,
"wires": [
[]
]
},
{
"id": "390254be.43b33c",
"type": "inject",
"z": "d7a593e6.9b06f",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "10",
"crontab": "",
"once": true,
"onceDelay": "10",
"x": 190,
"y": 1720,
"wires": [
[
"288a1c46.3e252c"
]
]
},
{
"id": "f5caadee.36e368",
"type": "inject",
"z": "d7a593e6.9b06f",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": "5",
"x": 190,
"y": 1540,
"wires": [
[]
]
},
{
"id": "db374884.bbed58",
"type": "ui_template",
"z": "d7a593e6.9b06f",
"group": "be53547b.4765a8",
"name": "relay-3-qrcode",
"order": 5,
"width": "3",
"height": "4",
"format": "<!DOCTYPE html>\n<div id=\"{{'qrcode-view-'+$id}}\">\n <p> {{ $label }} </p>\n <img id=\"{{'qrcode-viewer-'+$id}}\" style=\"{{'max-width:100%'}}\" src=\"{{$imageUrl}}\">\n</div>\n<script>\n(function(scope) {\n scope.$watch('msg', (msg) => {\n try {\n scope.$imageUrl = \"\";\n if (msg && msg.qrCodeAddress) {\n let blob;\n let payload = msg.qrCodeAddress;\n let contentType = \"png\";\n const deviceName = \"aloes-device\";\n scope.$label = 'IOTA address : ';\n scope.$deviceName = deviceName;\n if (msg.mimetype) contentType = msg.mimetype;\n // console.log(`new pic for ${deviceName}`, payload, typeof payload);\n if (payload && typeof payload === 'string') {\n scope.$imageUrl = payload;\n return msg;\n // const base64Flag = `data:image/${contentType};base64,`;\n // blob = (fetch(`${base64Flag}${payload}`)).blob();\n } else if (payload.type && payload.type === 'Buffer') {\n blob = new Blob([Uint8Array.from(payload.data)], { type: `image/${contentType}` });\n } else if (payload instanceof ArrayBuffer) {\n blob = new Blob([payload], { type: `image/${contentType}` });\n } else if (payload instanceof Array){\n blob = new Blob([Uint8Array.from(payload)], { type: `image/${contentType}`});\n } else {\n throw new Error(\"No valid payload to transform to blob\");\n }\n if (!blob) throw new Error(\"No Blob\");\n blob.lastModifiedDate = new Date();\n blob.name = deviceName;\n // console.log(`new blob for ${deviceName}`, blob)\n const urlCreator = window.URL || window.webkitURL;\n scope.$imageUrl = urlCreator.createObjectURL(blob);\n msg.payload = blob;\n // return msg;\n } \n if (msg && msg.transactions) {\n scope.$label = 'Transaction ongoing ...';\n scope.$imageUrl = `/icons/on.png`;\n }\n return null;;\n } catch(error){\n return error;\n }\n });\n})(scope);\n</script>",
"storeOutMessages": false,
"fwdInMessages": true,
"templateScope": "local",
"x": 720,
"y": 1800,
"wires": [
[]
]
},
{
"id": "b665e62b.fce488",
"type": "ui_text",
"z": "d7a593e6.9b06f",
"group": "be53547b.4765a8",
"order": 6,
"width": "4",
"height": "1",
"name": "",
"label": "IOTA balance",
"format": "{{msg.balance.balances[0]}}",
"layout": "row-spread",
"x": 700,
"y": 1660,
"wires": []
},
{
"id": "9cec8268.c56ef",
"type": "ui_text",
"z": "d7a593e6.9b06f",
"group": "be53547b.4765a8",
"order": 6,
"width": "4",
"height": "1",
"name": "",
"label": "IOTA price",
"format": "{{msg.payload}}",
"layout": "row-spread",
"x": 710,
"y": 1960,
"wires": []
},
{
"id": "f652f435.f5b108",
"type": "debug",
"z": "d7a593e6.9b06f",
"name": "",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"x": 530,
"y": 1860,
"wires": []
},
{
"id": "288a1c46.3e252c",
"type": "change",
"z": "d7a593e6.9b06f",
"name": "iota-price",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "iota-price-dollar",
"tot": "global"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 420,
"y": 1960,
"wires": [
[
"9cec8268.c56ef"
]
]
},
{
"id": "397660a2.c3b338",
"type": "subflow:2cff5c49.cc97e4",
"z": "d7a593e6.9b06f",
"name": "",
"env": [],
"x": 450,
"y": 1720,
"wires": [
[
"b665e62b.fce488"
],
[],
[
"db374884.bbed58"
]
]
},
{
"id": "17f979fb.d61896",
"type": "subflow:7c29baf0.0afbdc",
"z": "d7a593e6.9b06f",
"name": "",
"env": [],
"x": 460,
"y": 1540,
"wires": [
[]
]
},
{
"id": "6b98adbf.fda044",
"type": "status",
"z": "d7a593e6.9b06f",
"name": "",
"scope": [
"397660a2.c3b338",
"17f979fb.d61896"
],
"x": 980,
"y": 220,
"wires": [
[]
]
},
{
"id": "be53547b.4765a8",
"type": "ui_group",
"z": "d7a593e6.9b06f",
"name": "relay-3",
"tab": "fe99d4b2.836eb",
"order": 3,
"disp": true,
"width": "12",
"collapse": true
},
{
"id": "41c6c6f2.febed8",
"type": "subflow",
"name": "device-selected",
"info": "",
"category": "",
"in": [
{
"x": 200,
"y": 160,
"wires": [
{
"id": "fe378273.e7e4"
}
]
}
],
"out": [
{
"x": 460,
"y": 160,
"wires": [
{
"id": "fe378273.e7e4",
"port": 0
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
}
]
},
{
"id": "fe378273.e7e4",
"type": "function",
"z": "41c6c6f2.febed8",
"name": "isSelected",
"func": "try {\n const debug = env.get(\"debug\");\n const deviceName = env.get(\"device_name\");\n if (!deviceName) throw new Error(\"no device name env\");\n const compareNames = source => {\n if (source && source !== null) {\n return source === deviceName.toLowerCase();\n }\n return false;\n };\n const index = msg.payload.findIndex(compareNames);\n msg.payload = false;\n if (index > -1) {\n msg.payload = true;\n }\n if (debug) {\n console.log(\"isSelected\", index, msg.payload);\n }\n return msg;\n} catch(error) {\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 330,
"y": 160,
"wires": [
[]
]
},
{
"id": "d253d97e.e3e448",
"type": "subflow",
"name": "get-device",
"info": "",
"category": "function",
"in": [
{
"x": 160,
"y": 120,
"wires": [
{
"id": "b6b86bf5.bd0af"
}
]
}
],
"out": [
{
"x": 460,
"y": 120,
"wires": [
{
"id": "b6b86bf5.bd0af",
"port": 0
}
]
}
],
"env": [
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "store_type",
"type": "env",
"value": "store_type"
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
]
},
{
"id": "b6b86bf5.bd0af",
"type": "function",
"z": "d253d97e.e3e448",
"name": "getDevice",
"func": "try {\n const debug = env.get(\"debug\");\n const storeType = env.get(\"store_type\") || \"memoryOnly\";\n const deviceName = env.get(\"device_name\");\n if (!deviceName) throw new Error(\"Missing env vars\"); \n const storeKey = `device-${deviceName}`;\n if(!storeKey) throw new Error(\"Missing params\");\n if (debug) {\n console.log(\"get device store_key\", storeKey);\n }\n global.get(storeKey, storeType, (err,res) => {\n if(err) throw err;\n msg.device = res;\n }); \n if (!msg.device || msg.device === null) throw new Error(\"no device found\"); \n const userId = env.get(\"user_id\");\n msg.parts = [userId, \"Device\", \"HEAD\", msg.device.id];\n msg.topic = msg.parts.join(\"/\");\n if (debug) {\n console.log(\"get device topic\", msg.topic);\n }\n return msg;\n} catch(error) {\n // console.log(\"get device error\", error);\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 320,
"y": 120,
"wires": [
[]
]
},
{
"id": "8a55823f.f6ad1",
"type": "subflow",
"name": "get-sensor",
"info": "",
"category": "function",
"in": [
{
"x": 160,
"y": 200,
"wires": [
{
"id": "8fa149cd.a14938"
}
]
}
],
"out": [
{
"x": 440,
"y": 200,
"wires": [
{
"id": "8fa149cd.a14938",
"port": 0
}
]
}
],
"env": [
{
"name": "store_type",
"type": "env",
"value": "store_type"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "object_id",
"type": "str",
"value": "3300"
},
{
"name": "sensor_id",
"type": "str",
"value": "1"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
]
},
{
"id": "8fa149cd.a14938",
"type": "function",
"z": "8a55823f.f6ad1",
"name": "getSensor",
"func": "try {\n const debug = env.get(\"debug\");\n const storeType = env.get(\"store_type\") || \"memoryOnly\";\n const deviceName = env.get(\"device_name\");\n const objectId = env.get(\"object_id\");\n const nativeSensorId = env.get(\"sensor_id\");\n if (!deviceName || !objectId || !nativeSensorId) throw new Error(\"Missing env vars\"); \n const storeKey = `sensor-${deviceName}-${objectId}-${nativeSensorId}`;\n // console.log(\"save sensor storeKey : \", storeKey);\n if(!storeKey) throw new Error(\"Missing params\");\n if (debug) {\n console.log(\"get sensor store_key\", storeKey);\n }\n global.get(storeKey, storeType, (err,res) => {\n if(err) throw err;\n msg.sensor = res;\n }); \n if (!msg.sensor || msg.sensor === null) throw new Error(\"no sensor found\"); \n const userId = env.get(\"user_id\");\n msg.parts = [userId, \"Sensor\", \"HEAD\", msg.sensor.id];\n msg.topic = msg.parts.join(\"/\");\n if (debug) {\n console.log(\"get sensor topic\", msg.topic);\n }\n const resources = Object.keys(msg.sensor.resources);\n if (debug) {\n console.log(\"get sensor resources\", resources);\n }\n resources.forEach(resource => {\n msg.sensor.resource = Number(resource);\n msg.sensor.method = \"HEAD\";\n // msg.payload = msg.sensor.resources[resource];\n node.send(msg);\n });\n return null;\n} catch(error) {\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 290,
"y": 200,
"wires": [
[]
]
},
{
"id": "744e75eb.cf669c",
"type": "subflow",
"name": "set-instance",
"info": "**set-instance**\n\nSet device or sensor from incoming MQTT packet .\n\n`device_name` Name under which sensor or device is saved \n\n`debug` control debug display ( true / false ) \n\n`store_type` How to store instances ( \"memory\" / \"file\" ) \n",
"category": "storage",
"in": [
{
"x": 120,
"y": 220,
"wires": [
{
"id": "c0705021.3ee38"
}
]
}
],
"out": [
{
"x": 780,
"y": 80,
"wires": [
{
"id": "db98c356.1414",
"port": 0
}
]
},
{
"x": 780,
"y": 160,
"wires": [
{
"id": "cc6a3d07.dc47e",
"port": 0
}
]
},
{
"x": 780,
"y": 220,
"wires": [
{
"id": "c0705021.3ee38",
"port": 2
}
]
},
{
"x": 780,
"y": 300,
"wires": [
{
"id": "c0705021.3ee38",
"port": 3
}
]
},
{
"x": 780,
"y": 360,
"wires": [
{
"id": "93a425d1.a5175",
"port": 0
}
]
},
{
"x": 420,
"y": 460,
"wires": [
{
"id": "c0705021.3ee38",
"port": 5
}
]
}
],
"env": [
{
"name": "debug",
"type": "env",
"value": "debug"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "store_type",
"type": "env",
"value": "store_type"
}
],
"outputLabels": [
"device",
"sensor",
"measurement",
"status",
"trigger",
"debug"
],
"icon": "node-red/split.png"
},
{
"id": "c0705021.3ee38",
"type": "function",
"z": "744e75eb.cf669c",
"name": "dispatch-message",
"func": "try {\n if (!msg.topic) throw new Error(\"no msg.topic\");\n if (!msg.parts) {\n msg.parts = msg.topic.split(\"/\");\n }\n const debug = env.get(\"debug\");\n if (msg.device && msg.device !== null) {\n if (debug) {\n const message = {topic: msg.topic, payload : msg.device}\n return [msg, null, null, null, null, message];\n }\n return [msg, null, null, null,null, null];\n } else if (msg.sensor && msg.sensor !== null) {\n if (debug) {\n const message = {topic: msg.topic, payload : msg.sensor}\n return [null, msg, null, null, null, message];\n }\n return [null, msg, null, null, null, null];\n } else if (msg.measurement && msg.measurement !== null) {\n if (debug) {\n const message = {topic: msg.topic, payload : msg.measurement}\n return [null, null, msg, null, null, message];\n }\n return [null, null, msg, null, null, null];\n } else if (msg.status && msg.status !== null) {\n if (debug) {\n const message = {topic: msg.topic, payload : msg.status}\n return [null, null, null, msg, null, message];\n }\n return [null, null,null, msg, null, null];\n } else if (msg.trigger && msg.trigger !== null) {\n if (debug) {\n const message = {topic: msg.topic, payload : msg.trigger}\n return [null, null, null, null, msg, message];\n }\n return [null, null, null, null, msg, null];\n }\n return [null,null, null, null, null, null];\n} catch(error){\n return error;\n}",
"outputs": 6,
"noerr": 0,
"x": 270,
"y": 220,
"wires": [
[
"db98c356.1414"
],
[
"cc6a3d07.dc47e"
],
[],
[],
[
"93a425d1.a5175"
],
[]
],
"outputLabels": [
"device",
"sensor",
"measurement",
"status",
"trigger",
"debug"
]
},
{
"id": "cc6a3d07.dc47e",
"type": "function",
"z": "744e75eb.cf669c",
"name": "save-sensor",
"func": "try {\n const debug = env.get(\"debug\");\n const storeType = env.get(\"store_type\") || \"memoryOnly\";\n const deviceName = env.get(\"device_name\");\n if (!deviceName) throw new Error(\"Missing env vars\"); \n const objectId = msg.sensor.type;\n const nativeSensorId = msg.sensor.nativeSensorId;\n const storeKey = `sensor-${deviceName}-${objectId}-${nativeSensorId}`;\n if (debug) {\n console.log(\"save sensor storeKey : \", storeKey)\n }\n if(!storeKey) throw new Error(\"Missing params\");\n global.set(storeKey, msg.sensor, storeType, err => {\n if(err) throw err;\n }); \n return msg;\n} catch(error){\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 550,
"y": 160,
"wires": [
[]
]
},
{
"id": "db98c356.1414",
"type": "function",
"z": "744e75eb.cf669c",
"name": "save-device",
"func": "try {\n const debug = env.get(\"debug\");\n const storeType = env.get(\"store_type\") || \"memoryOnly\";\n const deviceName = env.get(\"device_name\");\n if (!deviceName) throw new Error(\"Missing env vars\"); \n let devicesList;\n global.get(\"devicesList\", storeType, (err, res) => {\n if (err) throw err;\n devicesList = res;\n });\n if (!devicesList || devicesList === null) {\n devicesList = [];\n }\n const index = devicesList.indexOf(deviceName);\n if (debug) {\n console.log(\"save device, index\", deviceName, index)\n }\n if (index === -1) {\n devicesList.push(deviceName);\n global.set(\"devicesList\", devicesList, \"memoryOnly\", err => {\n if (err) throw err;\n });\n }\n if (debug) {\n console.log(\"update devices list\", devicesList)\n }\n const storeKey = `device-${deviceName}`;\n // console.log(\"saveDevice storeKey : \", storeKey);\n if(!storeKey) throw new Error(\"Missing params\");\n global.set(storeKey, msg.device, storeType, err => {\n if(err) throw err;\n }); \n return msg;\n} catch(error){\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 550,
"y": 80,
"wires": [
[]
]
},
{
"id": "93a425d1.a5175",
"type": "function",
"z": "744e75eb.cf669c",
"name": "dispatch-trigger",
"func": "if (!msg.deviceName) return null;\nconst deviceName = env.get(\"device_name\");\nif (msg.deviceName === deviceName) {\n // console.log(\"trigger device\", deviceName);\n return msg;\n}\nreturn null;",
"outputs": 1,
"noerr": 0,
"x": 580,
"y": 360,
"wires": [
[]
]
},
{
"id": "541e2a83.f89d2c",
"type": "subflow",
"name": "relay-logic",
"info": "**relay-logic**\n\n- Plug it after a aloes-client node\n- Set device_name and device id ( from your Aloes account)\n- Output whole device object and sensor properties \n",
"category": "relays",
"in": [
{
"x": 120,
"y": 160,
"wires": [
{
"id": "93a044c9.11dcf"
}
]
}
],
"out": [
{
"x": 960,
"y": 160,
"wires": [
{
"id": "2db0a42e.b4d71c",
"port": 0
}
]
},
{
"x": 1100,
"y": 380,
"wires": [
{
"id": "637db151.0af558",
"port": 0
}
]
},
{
"x": 1100,
"y": 440,
"wires": [
{
"id": "637db151.0af558",
"port": 1
}
]
},
{
"x": 1100,
"y": 500,
"wires": [
{
"id": "2e574679.b2d8e2",
"port": 0
}
]
},
{
"x": 1100,
"y": 560,
"wires": [
{
"id": "2e574679.b2d8e2",
"port": 1
}
]
},
{
"x": 520,
"y": 160,
"wires": [
{
"id": "93a044c9.11dcf",
"port": 2
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "true"
},
{
"name": "device_id",
"type": "env",
"value": "device_id"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "store_type",
"type": "env",
"value": "store_type"
}
],
"outputLabels": [
"device-properties",
"3306/1/5850",
"3306/2/5850",
"3306/1/5851",
"3306/2/5851",
"measurements"
],
"icon": "node-red/batch.png"
},
{
"id": "50704266.5e504c",
"type": "debug",
"z": "541e2a83.f89d2c",
"name": "${device_name}",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"x": 260,
"y": 260,
"wires": []
},
{
"id": "93a044c9.11dcf",
"type": "subflow:744e75eb.cf669c",
"z": "541e2a83.f89d2c",
"name": "",
"env": [],
"x": 250,
"y": 160,
"wires": [
[
"fdb9d533.e19868"
],
[
"fcb81d77.cdf288"
],
[],
[],
[
"36958eb7.5fcc3a"
],
[
"50704266.5e504c"
]
]
},
{
"id": "563e9526.976dcc",
"type": "link out",
"z": "541e2a83.f89d2c",
"name": "filter-sensors->",
"links": [
"23308ffb.34f538"
],
"x": 475,
"y": 1080,
"wires": []
},
{
"id": "1d21eb0d.3992cd",
"type": "comment",
"z": "541e2a83.f89d2c",
"name": "Refresh interfaces",
"info": "",
"x": 190,
"y": 920,
"wires": []
},
{
"id": "70bdc8fa.e3edd",
"type": "switch",
"z": "541e2a83.f89d2c",
"name": "objectId",
"property": "sensor.type",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "3306",
"vt": "num"
}
],
"checkall": "false",
"repair": false,
"outputs": 1,
"x": 460,
"y": 460,
"wires": [
[
"5ba11bd4.91ef5c"
]
]
},
{
"id": "5ba11bd4.91ef5c",
"type": "switch",
"z": "541e2a83.f89d2c",
"name": "3306-resourceId",
"property": "sensor.resource",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "5850",
"vt": "num"
},
{
"t": "eq",
"v": "5851",
"vt": "num"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 650,
"y": 460,
"wires": [
[
"637db151.0af558"
],
[
"2e574679.b2d8e2"
]
]
},
{
"id": "637db151.0af558",
"type": "switch",
"z": "541e2a83.f89d2c",
"name": "5850-sensorId",
"property": "sensor.nativeSensorId",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "1",
"vt": "str"
},
{
"t": "eq",
"v": "2",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 900,
"y": 400,
"wires": [
[],
[]
]
},
{
"id": "2e574679.b2d8e2",
"type": "switch",
"z": "541e2a83.f89d2c",
"name": "5851-sensorId",
"property": "sensor.nativeSensorId",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "1",
"vt": "str"
},
{
"t": "eq",
"v": "2",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 900,
"y": 540,
"wires": [
[],
[]
]
},
{
"id": "23308ffb.34f538",
"type": "link in",
"z": "541e2a83.f89d2c",
"name": "->filter-sensors",
"links": [
"563e9526.976dcc",
"fcb81d77.cdf288"
],
"x": 115,
"y": 460,
"wires": [
[
"b91730d1.f86b68"
]
]
},
{
"id": "2db0a42e.b4d71c",
"type": "link in",
"z": "541e2a83.f89d2c",
"name": "device-output",
"links": [
"fdb9d533.e19868",
"81cbe34b.06af6"
],
"x": 855,
"y": 160,
"wires": [
[]
]
},
{
"id": "cf3bc26.d0dddc",
"type": "subflow:8a55823f.f6ad1",
"z": "541e2a83.f89d2c",
"name": "get-sensor-3306-1",
"env": [
{
"name": "object_id",
"type": "str",
"value": "3306"
}
],
"x": 270,
"y": 1080,
"wires": [
[
"563e9526.976dcc"
]
]
},
{
"id": "e795b603.cc8d98",
"type": "comment",
"z": "541e2a83.f89d2c",
"name": "FLOW OUPUT",
"info": "",
"x": 920,
"y": 80,
"wires": []
},
{
"id": "e6306fac.b85248",
"type": "comment",
"z": "541e2a83.f89d2c",
"name": "Filter sensor properties",
"info": "",
"x": 200,
"y": 360,
"wires": []
},
{
"id": "fcb81d77.cdf288",
"type": "link out",
"z": "541e2a83.f89d2c",
"name": "filter-sensors->",
"links": [
"23308ffb.34f538"
],
"x": 455,
"y": 120,
"wires": []
},
{
"id": "3c561da6.9cb002",
"type": "comment",
"z": "541e2a83.f89d2c",
"name": "FLOW INPUT",
"info": "",
"x": 170,
"y": 40,
"wires": []
},
{
"id": "fdb9d533.e19868",
"type": "link out",
"z": "541e2a83.f89d2c",
"name": "filter-device->",
"links": [
"2db0a42e.b4d71c"
],
"x": 455,
"y": 80,
"wires": []
},
{
"id": "e50400cd.bcdbc",
"type": "subflow:d253d97e.e3e448",
"z": "541e2a83.f89d2c",
"name": "",
"env": [],
"x": 250,
"y": 1020,
"wires": [
[
"81cbe34b.06af6"
]
]
},
{
"id": "81cbe34b.06af6",
"type": "link out",
"z": "541e2a83.f89d2c",
"name": "filter-device->",
"links": [
"2db0a42e.b4d71c"
],
"x": 475,
"y": 1020,
"wires": []
},
{
"id": "3a4758b3.aeb568",
"type": "comment",
"z": "541e2a83.f89d2c",
"name": "Filter triggers",
"info": "",
"x": 170,
"y": 700,
"wires": []
},
{
"id": "13c79f77.2f0cd9",
"type": "link in",
"z": "541e2a83.f89d2c",
"name": "->filter-triggers",
"links": [
"36958eb7.5fcc3a"
],
"x": 115,
"y": 780,
"wires": [
[
"34774e53.09c2e2"
]
]
},
{
"id": "34774e53.09c2e2",
"type": "switch",
"z": "541e2a83.f89d2c",
"name": "Command",
"property": "trigger",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "refresh",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 1,
"x": 310,
"y": 780,
"wires": [
[
"d91faba6.1e8428"
]
]
},
{
"id": "d91faba6.1e8428",
"type": "switch",
"z": "541e2a83.f89d2c",
"name": "Collection",
"property": "collection",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "sensor",
"vt": "str"
},
{
"t": "eq",
"v": "device",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 2,
"x": 660,
"y": 780,
"wires": [
[
"abaa1559.dce508"
],
[
"e5e79c5f.3b96f8"
]
]
},
{
"id": "abaa1559.dce508",
"type": "link out",
"z": "541e2a83.f89d2c",
"name": "trigger-refresh-sensor->",
"links": [
"8f141a95.1a1ee8"
],
"x": 1035,
"y": 740,
"wires": []
},
{
"id": "e5e79c5f.3b96f8",
"type": "link out",
"z": "541e2a83.f89d2c",
"name": "trigger-refresh-device->",
"links": [
"6c1b730a.d4e144"
],
"x": 1035,
"y": 820,
"wires": []
},
{
"id": "6c1b730a.d4e144",
"type": "link in",
"z": "541e2a83.f89d2c",
"name": "->trigger-refresh-device",
"links": [
"e5e79c5f.3b96f8"
],
"x": 115,
"y": 1020,
"wires": [
[
"e50400cd.bcdbc"
]
]
},
{
"id": "36958eb7.5fcc3a",
"type": "link out",
"z": "541e2a83.f89d2c",
"name": "filter-triggers->",
"links": [
"13c79f77.2f0cd9"
],
"x": 455,
"y": 220,
"wires": []
},
{
"id": "8f141a95.1a1ee8",
"type": "link in",
"z": "541e2a83.f89d2c",
"name": "->trigger-refresh-sensors",
"links": [
"abaa1559.dce508"
],
"x": 115,
"y": 1080,
"wires": [
[
"cf3bc26.d0dddc"
]
]
},
{
"id": "b91730d1.f86b68",
"type": "change",
"z": "541e2a83.f89d2c",
"name": "",
"rules": [
{
"t": "set",
"p": "method",
"pt": "msg",
"to": "parts[2]",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 260,
"y": 460,
"wires": [
[
"70bdc8fa.e3edd"
]
]
},
{
"id": "8ff67ce6.9014f",
"type": "subflow",
"name": "set-custom-btn",
"info": "",
"category": "",
"in": [
{
"x": 220,
"y": 160,
"wires": [
{
"id": "7234cf4c.dc519"
}
]
}
],
"out": [
{
"x": 460,
"y": 160,
"wires": [
{
"id": "7234cf4c.dc519",
"port": 0
}
]
}
],
"env": [
{
"name": "label_true",
"type": "str",
"value": ""
},
{
"name": "tooltip_true",
"type": "str",
"value": ""
},
{
"name": "topic_true",
"type": "str",
"value": ""
},
{
"name": "payload_true",
"type": "str",
"value": ""
},
{
"name": "color_true",
"type": "str",
"value": ""
},
{
"name": "bg_color_true",
"type": "str",
"value": ""
},
{
"name": "label_false",
"type": "str",
"value": ""
},
{
"name": "tooltip_false",
"type": "str",
"value": ""
},
{
"name": "topic_false",
"type": "str",
"value": ""
},
{
"name": "payload_false",
"type": "str",
"value": ""
},
{
"name": "color_false",
"type": "str",
"value": ""
},
{
"name": "bg_color_false",
"type": "str",
"value": ""
}
]
},
{
"id": "7234cf4c.dc519",
"type": "function",
"z": "8ff67ce6.9014f",
"name": "",
"func": "try {\n if (msg.payload === true || msg.payload === \"true\") {\n msg.label = env.get(\"label_true\") || \"Remove\";\n msg.tooltip = env.get(\"tooltip_true\") || \"Remove from device selection\";\n msg.topic = env.get(\"topic_true\") || \"DELETE/devicesSelection\";\n msg.payload = env.get(\"payload_true\") || true;\n } else if (msg.payload === false || msg.payload === \"false\") {\n msg.payload = env.get(\"payload_false\") || false;\n msg.label = env.get(\"label_false\") || \"Add\";\n msg.tooltip = env.get(\"tooltip_false\") || \"Add to device selection\";\n msg.topic = env.get(\"topic_false\") || \"POST/devicesSelection\"; \n } else {\n msg.enabled = false;\n }\n return msg;\n} catch(error) {\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 350,
"y": 160,
"wires": [
[]
]
},
{
"id": "32f8e46a.971f8c",
"type": "subflow",
"name": "select-device-update",
"info": "",
"category": "",
"in": [
{
"x": 340,
"y": 300,
"wires": [
{
"id": "9191679b.289108"
}
]
}
],
"out": [
{
"x": 580,
"y": 300,
"wires": [
{
"id": "9191679b.289108",
"port": 0
}
]
}
],
"env": [
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "store_type",
"type": "env",
"value": "store_type"
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
]
},
{
"id": "9191679b.289108",
"type": "function",
"z": "32f8e46a.971f8c",
"name": "",
"func": "try {\n const debug = env.get(\"debug\");\n const deviceName = env.get(\"device_name\");\n if (!deviceName) throw new Error(\"no device name env\");\n const storeType = env.get(\"store_type\") || \"file\";\n let selection;\n \n global.get(\"devicesSelection\", storeType, (err,res) => {\n if (err) throw err;\n selection = res || [];\n });\n if (msg.payload === false) {\n const index = selection.indexOf(deviceName);\n if (index > -1) {\n selection.splice(index, 1);\n global.set(\"devicesSelection\", selection, storeType, err => {\n if (err) throw err;\n });\n }\n } else if (msg.payload === true) {\n const index = selection.indexOf(deviceName);\n if (index === -1) {\n selection.push(deviceName);\n global.set(\"devicesSelection\", selection, storeType, err => {\n if (err) throw err;\n });\n }\n }\n if (debug) {\n console.log(\"update device selection\", selection);\n }\n // msg.payload = selection;\n return msg;\n} catch(error) {\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 470,
"y": 300,
"wires": [
[]
]
},
{
"id": "1e071b74.a346dd",
"type": "subflow",
"name": "set-boolean",
"info": "",
"category": "function",
"in": [
{
"x": 380,
"y": 120,
"wires": [
{
"id": "756683ff.5394ac"
}
]
}
],
"out": [
{
"x": 740,
"y": 120,
"wires": [
{
"id": "756683ff.5394ac",
"port": 0
}
]
}
],
"env": [
{
"name": "resource_id",
"type": "str",
"value": ""
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"icon": "font-awesome/fa-check"
},
{
"id": "756683ff.5394ac",
"type": "function",
"z": "1e071b74.a346dd",
"name": "setBoolean",
"func": "try {\n const debug = env.get(\"debug\");\n if (!msg || msg === null || !msg.sensor) throw new Error(\"No input to parse\");\n const resourceId = env.get(\"resource_id\");\n if (!resourceId) throw new Error(\"no resource id set\")\n const value = msg.sensor.resources[resourceId];\n // const value = msg.sensor.value;\n if (debug) {\n console.log(`get-boolean for ${resourceId} : ${typeof value}`)\n }\n if (typeof value === \"string\") {\n msg.payload = value; \n } else if (typeof value === \"number\") {\n msg.payload = value.toString(); \n } else if (typeof value === \"boolean\") {\n msg.payload = value; \n } else if (typeof value === \"object\" && value.type && value.data){\n // msg.payload = value.data.toString('utf-8');\n msg.payload = Buffer.from(value.data).toString('utf-8');\n } else if (Buffer.isBuffer(value)){\n msg.payload = value.toString('utf-8');\n } else if (value instanceof Array) {\n msg.payload = Buffer.from(value).toString('utf-8');\n } else {\n throw new Error(\"No value found\")\n }\n if (msg.payload === \"true\" || msg.payload === \"1\" || msg.payload === 1) {\n msg.payload = true;\n } else if (msg.payload === \"false\" || msg.payload === \"0\" || msg.payload === 0) {\n msg.payload = false;\n }\n if (debug) {\n console.log(`set-boolean for ${resourceId} : ${msg.payload}`)\n }\n return msg;\n} catch(error) {\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 550,
"y": 120,
"wires": [
[]
]
},
{
"id": "de56f8d.072c908",
"type": "subflow",
"name": "set-topic",
"info": "",
"category": "function",
"in": [
{
"x": 260,
"y": 160,
"wires": [
{
"id": "134d435d.20bced"
}
]
}
],
"out": [
{
"x": 600,
"y": 160,
"wires": [
{
"id": "134d435d.20bced",
"port": 0
}
]
}
],
"env": [
{
"name": "collection",
"type": "str",
"value": "sensor"
},
{
"name": "method",
"type": "str",
"value": "HEAD"
},
{
"name": "sensor_id",
"type": "str",
"value": "1"
},
{
"name": "object_id",
"type": "str",
"value": "3300"
},
{
"name": "resource_id",
"type": "str",
"value": "5700"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "save_instance",
"type": "bool",
"value": "false"
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
]
},
{
"id": "134d435d.20bced",
"type": "function",
"z": "de56f8d.072c908",
"name": "setTopic",
"func": "try {\n const debug = env.get(\"debug\");\n const userId = env.get(\"user_id\");\n const save = env.get(\"save_instance\");\n if (!userId ) throw new Error(\"Missing params\"); \n if (save) {\n msg.save = save;\n }\n if (debug) {\n console.log(\"get-topic\", msg.topic, msg.save)\n }\n if (!msg.sensor) {\n const method = env.get(\"method\") || \"HEAD\";\n const collection = env.get(\"collection\") || \"sensor\";\n const objectId = env.get(\"object_id\") || \"3300\";\n const instanceId = env.get(\"sensor_id\");\n const resourceId = env.get(\"resource_id\");\n msg.topic = `${method}/${collection}/${objectId}/${instanceId}/${resourceId}`;\n if (debug) {\n console.log(\"set-topic from empty\", msg.topic)\n }\n return msg;\n } else if (msg.sensor && msg.sensor.method && msg.sensor.method === \"HEAD\") {\n if (debug) {\n console.log(\"get-topic\", msg.sensor.method)\n }\n return null;\n } else if (msg.topic.startsWith(userId) && msg.parts) {\n const method = msg.parts[2];\n const collection = msg.parts[1].toLowerCase();\n const objectId = msg.sensor.type;\n const instanceId = msg.sensor.nativeSensorId;\n const resourceId = msg.sensor.resource;\n msg.topic = `${method}/${collection}/${objectId}/${instanceId}/${resourceId}`;\n if (debug) {\n console.log(\"set-topic from existing\", msg.topic)\n }\n return msg;\n }\n return null;\n} catch(error) {\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 420,
"y": 160,
"wires": [
[]
]
},
{
"id": "f8bab707.28f4c",
"type": "subflow",
"name": "set-float",
"info": "",
"category": "function",
"in": [
{
"x": 180,
"y": 120,
"wires": [
{
"id": "a0f0056c.777e6"
}
]
}
],
"out": [
{
"x": 440,
"y": 120,
"wires": [
{
"id": "a0f0056c.777e6",
"port": 0
}
]
}
],
"env": [
{
"name": "resource_id",
"type": "str",
"value": ""
},
{
"name": "precision",
"type": "num",
"value": "0"
},
{
"name": "unit",
"type": "str",
"value": ""
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"icon": "font-awesome/fa-check"
},
{
"id": "a0f0056c.777e6",
"type": "function",
"z": "f8bab707.28f4c",
"name": "setFloat",
"func": "try {\n const debug = env.get(\"debug\");\n if (!msg || msg === null || !msg.sensor) throw new Error(\"No input to parse\");\n const resourceId = env.get(\"resource_id\");\n if (!resourceId) throw new Error(\"no resource id set\")\n let value = msg.sensor.resources[resourceId];\n // const value = msg.sensor.value;\n if (value === undefined || value === null) throw new Error(\"no sensor value found\")\n if (debug) {\n console.log(`get-float for ${resourceId} :`, typeof value, value)\n }\n if (typeof value === \"object\" && value.type && value.data){\n value = Buffer.from(value).toString('utf-8');\n } else if (Buffer.isBuffer(value)){\n value = value.toString('utf-8');\n } else if (value instanceof Array) {\n value = Buffer.from(value).toString('utf-8');\n }\n if (typeof value === \"string\") {\n if (value === \"1\" || value === \"true\") {\n msg.payload = 1;\n } else if (value === \"0\" || value === \"false\") {\n msg.payload = 0;\n } else {\n msg.payload = Number(value); \n }\n } else if (typeof value === \"number\") {\n msg.payload = value;\n } else if (typeof value === \"boolean\") {\n if (value === true) {\n msg.payload = 1;\n } else if (value === false) {\n msg.payload = 0;\n } \n } else throw new Error(\"no valid payload to parse\");\n \n if (msg.payload === undefined) throw new Error(\"no payload\");\n const precision = env.get(\"precision\") || msg.sensor.resources[\"5701\"] || null;\n const unit = env.get(\"unit\");\n if (unit && unit !== null) {\n msg.unit = unit;\n }\n //msg.payload = Number(msg.payload);\n //if (precision && precision !== null) {\n // msg.payload = msg.payload.toPrecision(precision)\n //}\n if (debug) {\n console.log(`set-float for ${resourceId} : ${msg.payload}`)\n }\n return msg;\n} catch(error) {\n return error;\n}",
"outputs": 1,
"noerr": 0,
"x": 330,
"y": 120,
"wires": [
[]
]
},
{
"id": "2188cc9a.23fde4",
"type": "subflow",
"name": "update-instance",
"info": "**update-instance**\n\nFind and update device or sensor from incoming msg.topic.\n\nValidate payload before publishing via MQTT.\n\n`user_id` aloes user id ( default : set from `ALOES_USER_ID` )\n\n`device_name` Name under which sensor or device is saved \n\n`debug` control debug display ( true / false ) \n\n`store_type` How to store instances ( \"memory\" / \"file\" ) \n",
"category": "storage",
"in": [
{
"x": 100,
"y": 220,
"wires": [
{
"id": "200e493e.d70e76"
}
]
}
],
"out": [
{
"x": 820,
"y": 220,
"wires": [
{
"id": "575059b0.8d7a2",
"port": 0
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
},
{
"name": "store_type",
"type": "env",
"value": ""
},
{
"name": "user_id",
"type": "env",
"value": ""
},
{
"name": "device_name",
"type": "str",
"value": ""
},
{
"name": "print_debug",
"type": "bool",
"value": "false"
}
],
"icon": "node-red/split.png"
},
{
"id": "200e493e.d70e76",
"type": "function",
"z": "2188cc9a.23fde4",
"name": "find-instance",
"func": "try {\n // pattern : POST/sensor/3339/3/5523\n if (msg.topic) {\n const t = msg.topic.split(\"/\");\n const storeType = env.get(\"store_type\") || \"memoryOnly\";\n const deviceName = env.get(\"device_name\") || t[0];\n const debug = env.get(\"debug\");\n const userId = env.get(\"user_id\");\n if (debug) {\n console.log(\"instance payload: \", deviceName, msg.topic, msg.payload);\n }\n if (msg.payload === undefined) throw new Error(\"Missing payload\"); \n if (!userId || !deviceName) throw new Error(\"Missing env vars\"); \n const method = t[0];\n const collection = t[1].toLowerCase();\n const objectId = t[2];\n const nativeSensorId = t[3];\n const resourceId = t[4];\n const collectionName = `${collection.charAt(0).toUpperCase()}${collection.slice(1)}`;\n\n if (debug) {\n console.log(\"instance topic: \", method, collectionName, objectId);\n }\n\n let storeKey;\n if (collection === \"sensor\" && objectId && nativeSensorId) {\n storeKey = `sensor-${deviceName}-${objectId}-${nativeSensorId}`;\n } else if (collection === \"device\") {\n storeKey = `device-${deviceName}`;\n }\n if (debug) {\n console.log(\"findInstance storeKey : \", storeKey);\n }\n if(!storeKey) throw new Error(\"Missing params\");\n let instance;\n global.get(storeKey, storeType, (err, res) => {\n if(err) throw err;\n instance = res;\n // return instance;\n }); \n if (!instance) throw new Error('No instance found');\n if (debug) {\n console.log(\"foundInstance: \", instance.name);\n }\n if (method === \"POST\") {\n msg.topic = `${userId}/${collectionName}/${method}`;\n } else {\n msg.topic = `${userId}/${collectionName}/${method}/${instance.id}`;\n }\n // msg.topic = `${userId}/IoTAgent/${method}/${instance.id}`;\n\n msg[collection] = instance;\n msg.value = msg.payload;\n msg.resource = resourceId;\n msg.method = method;\n msg.attribute = objectId;\n msg.deviceName = deviceName;\n if (debug) {\n console.log(\"instance params: \", msg.topic, msg.resource);\n }\n return msg;\n }\n throw new Error(\"Missing params\");\n} catch(error){\n return error;\n}\n",
"outputs": 1,
"noerr": 0,
"x": 250,
"y": 220,
"wires": [
[
"4c607fd0.a70968"
]
]
},
{
"id": "4c607fd0.a70968",
"type": "function",
"z": "2188cc9a.23fde4",
"name": "update-instance",
"func": "try {\n const debug = env.get(\"debug\");\n const storeType = env.get(\"store_type\") || \"memoryOnly\";\n // console.log(\"resource : \", msg.resource);\n // if (msg.payload === undefined) throw new Error(\"undefined sensor value\");\n if (msg.device) {\n msg.payload = msg.device;\n }\n if (msg.sensor && msg.resource) {\n let updater; \n global.get(\"aloesHandlers\", storeType, (err,res) => {\n if (err) throw err;\n updater = res.updateAloesSensors;\n });\n if (!updater) throw new Error(\"Can't import Aloes Handlers\");\n if (debug) {\n console.log(\"updateInstance value type: \", typeof msg.payload);\n }\n const sensor = updater(msg.sensor, Number(msg.resource), msg.payload);\n if (!sensor || sensor === null ) throw new Error(\"Error while updating sensor\");\n if (debug) {\n console.log(\"updateInstance : \", sensor.name, sensor.resource);\n }\n sensor.method = msg.method;\n msg.payload = sensor;\n if (msg instanceof Error) {\n console.log(\"updateInstance Error : \",msg)\n }\n if (debug) {\n return [msg, msg];\n }\n\n return [msg,null];\n // return msg;\n }\n throw new Error(\"no sensor instance\");\n} catch(error){\n return error;\n}\n",
"outputs": 2,
"noerr": 0,
"x": 420,
"y": 220,
"wires": [
[
"575059b0.8d7a2"
],
[
"8c068de2.ed7d48"
]
]
},
{
"id": "8c068de2.ed7d48",
"type": "debug",
"z": "2188cc9a.23fde4",
"name": "updateInstance",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 560,
"y": 280,
"wires": []
},
{
"id": "575059b0.8d7a2",
"type": "function",
"z": "2188cc9a.23fde4",
"name": "print-debug",
"func": "try {\n if (env.get(\"print_debug\")) {\n const d = new Date();\n const filename = './log/game.log';\n let payload;\n if (msg.sensor) {\n payload = `${d.toLocaleString()}-update sensor-${msg.deviceName}-${msg.sensor.nativeSensorId}-${msg.sensor.resource}`;\n delete msg.sensor;\n } else if (msg.device) {\n payload = `${d.toLocaleString()}-update device-${msg.deviceName}`;\n delete msg.device;\n }\n const message = {payload, filename};\n console.log(\"print debug : \", message);\n delete msg.deviceName;\n delete msg.collection\n return [msg, message];\n }\n if (msg.sensor) {\n delete msg.sensor;\n } else if (msg.device) {\n delete msg.device;\n }\n delete msg.deviceName;\n return msg;\n} catch(error) {\n return error;\n}\n",
"outputs": 2,
"noerr": 0,
"x": 610,
"y": 220,
"wires": [
[],
[
"de459056.eb403"
]
]
},
{
"id": "de459056.eb403",
"type": "file",
"z": "2188cc9a.23fde4",
"name": "",
"filename": "",
"appendNewline": true,
"createDir": true,
"overwriteFile": "false",
"encoding": "none",
"x": 820,
"y": 300,
"wires": [
[]
]
},
{
"id": "2ee26e35.8449fa",
"type": "subflow",
"name": "relay-2",
"info": "",
"category": "relays",
"in": [
{
"x": 100,
"y": 240,
"wires": [
{
"id": "12832e27.fc6972"
}
]
}
],
"out": [
{
"x": 1000,
"y": 140,
"wires": [
{
"id": "bc76f9da.f42198",
"port": 0
}
]
}
],
"env": [
{
"name": "debug",
"type": "bool",
"value": "true"
},
{
"name": "device_id",
"type": "str",
"value": ""
},
{
"name": "device_name",
"type": "str",
"value": ""
},
{
"name": "user_id",
"type": "env",
"value": "ALOES_USER_ID"
},
{
"name": "store_type",
"type": "env",
"value": "NODE_RED_STORE_TYPE"
}
],
"icon": "font-awesome/fa-desktop"
},
{
"id": "5d8c2c55.f50524",
"type": "subflow:2188cc9a.23fde4",
"z": "2ee26e35.8449fa",
"name": "",
"env": [
{
"name": "store_type",
"type": "env",
"value": "store_type"
},
{
"name": "user_id",
"type": "env",
"value": "user_id"
},
{
"name": "device_name",
"type": "env",
"value": "device_name"
}
],
"x": 960,
"y": 960,
"wires": [
[
"bee6058a.1a1338"
]
]
},
{
"id": "a563aa2.0d976d8",
"type": "link in",
"z": "2ee26e35.8449fa",
"name": "SWITCH/3306/1/5850",
"links": [
"6ebc5321.231784",
"3e27e76b.8276c8",
"7159c220.3bc1a4",
"63d58f38.04b448",
"698d949a.0640ec"
],
"x": 95,
"y": 860,
"wires": [
[
"ee3ae218.4efd8"
]
]
},
{
"id": "da0f5cab.fbc728",
"type": "link in",
"z": "2ee26e35.8449fa",
"name": "SWITCH/3306/2/5850",
"links": [
"2e437bca.ef24cc",
"8ce277c5.1c50c",
"de208161.34e88"
],
"x": 95,
"y": 980,
"wires": [
[]
]
},
{
"id": "7ee0fa4b.6be53c",
"type": "link in",
"z": "2ee26e35.8449fa",
"name": "",
"links": [
"5be1c64f.0fc09",
"3c878298.7bd916",
"62c400a9.0a12a",
"54a0dc24.93a7ac",
"15fb67f4.b91048"
],
"x": 95,
"y": 1040,
"wires": [
[
"7afda883.7816e"
]
]
},
{
"id": "4d94be31.b0137",
"type": "link in",
"z": "2ee26e35.8449fa",
"name": "",
"links": [
"1c4140f8.1f8b77",
"d1180bc2.2d49f",
"c4b71e5e.b9de58"
],
"x": 95,
"y": 1140,
"wires": [
[]
]
},
{
"id": "e9fdfed3.d04b08",
"type": "ui_switch",
"z": "2ee26e35.8449fa",
"name": "PUT/sensor/3306/1/5850",
"label": "switch",
"tooltip": "Turn on/off relay",
"group": "92ed92ec.2f98f8",
"order": 2,
"width": "6",
"height": "1",
"passthru": false,
"decouple": "false",
"topic": "",
"style": "",
"onvalue": "true",
"onvalueType": "bool",
"onicon": "",
"oncolor": "",
"offvalue": "false",
"offvalueType": "bool",
"officon": "",
"offcolor": "",
"x": 450,
"y": 860,
"wires": [
[
"12afab28.373b55",
"72592224.052f84"
]
]
},
{
"id": "72592224.052f84",
"type": "ui_chart",
"z": "2ee26e35.8449fa",
"name": "",
"group": "92ed92ec.2f98f8",
"order": 4,
"width": "6",
"height": "5",
"label": "3306/1/5850",
"chartType": "line",
"legend": "false",
"xformat": "HH:mm:ss",
"interpolate": "step",
"nodata": "",
"dot": false,
"ymin": "0",
"ymax": "1",
"removeOlder": 1,
"removeOlderPoints": "",
"removeOlderUnit": "3600",
"cutout": 0,
"useOneColor": false,
"colors": [
"#1f77b4",
"#aec7e8",
"#ff7f0e",
"#2ca02c",
"#98df8a",
"#d62728",
"#ff9896",
"#9467bd",
"#c5b0d5"
],
"useOldStyle": false,
"outputs": 1,
"x": 470,
"y": 920,
"wires": [
[]
]
},
{
"id": "1fefe39c.a9f204",
"type": "change",
"z": "2ee26e35.8449fa",
"name": "PUT/sensor/3306/1/5850",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "PUT/sensor/3306/1/5850",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 290,
"y": 1320,
"wires": [
[]
]
},
{
"id": "9e1f0f6a.2167b8",
"type": "comment",
"z": "2ee26e35.8449fa",
"name": "Sensor properties",
"info": "",
"x": 165,
"y": 780,
"wires": []
},
{
"id": "ba4045a4.57fff8",
"type": "comment",
"z": "2ee26e35.8449fa",
"name": "Scenario",
"info": "",
"x": 140,
"y": 1260,
"wires": []
},
{
"id": "87655fd.2c310a",
"type": "ui_slider",
"z": "2ee26e35.8449fa",
"name": "PUT/sensor/3306/1/5851",
"label": "slider",
"tooltip": "",
"group": "92ed92ec.2f98f8",
"order": 3,
"width": "6",
"height": "1",
"passthru": true,
"outs": "end",
"topic": "",
"min": 0,
"max": "100",
"step": 1,
"x": 450,
"y": 1040,
"wires": [
[
"6cf9ddd6.3412f4"
]
]
},
{
"id": "7afda883.7816e",
"type": "subflow:f8bab707.28f4c",
"z": "2ee26e35.8449fa",
"name": "",
"env": [
{
"name": "resource_id",
"type": "str",
"value": "5851"
},
{
"name": "precision",
"type": "num",
"value": "1"
},
{
"name": "unit",
"type": "str",
"value": "%"
}
],
"x": 200,
"y": 1040,
"wires": [
[
"87655fd.2c310a"
]
]
},
{
"id": "73409d03.5b7044",
"type": "link in",
"z": "2ee26e35.8449fa",
"name": "SWITCH/3306/1/5850",
"links": [
"6ebc5321.231784",
"3e27e76b.8276c8",
"7159c220.3bc1a4"
],
"x": 95,
"y": 1320,
"wires": [
[
"1fefe39c.a9f204"
]
]
},
{
"id": "bc76f9da.f42198",
"type": "link in",
"z": "2ee26e35.8449fa",
"name": "subflow-output",
"links": [
"bee6058a.1a1338"
],
"x": 895,
"y": 140,
"wires": [
[]
]
},
{
"id": "bee6058a.1a1338",
"type": "link out",
"z": "2ee26e35.8449fa",
"name": "updated-instance->",
"links": [
"bc76f9da.f42198"
],
"x": 1115,
"y": 960,
"wires": []
},
{
"id": "12afab28.373b55",
"type": "subflow:de56f8d.072c908",
"z": "2ee26e35.8449fa",
"name": "",
"env": [
{
"name": "method",
"type": "str",
"value": "PUT"
},
{
"name": "object_id",
"type": "str",
"value": "3306"
},
{
"name": "resource_id",
"type": "str",
"value": "5850"
}
],
"x": 680,
"y": 860,
"wires": [
[
"5d8c2c55.f50524"
]
]
},
{
"id": "6cf9ddd6.3412f4",
"type": "subflow:de56f8d.072c908",
"z": "2ee26e35.8449fa",
"name": "",
"env": [
{
"name": "method",
"type": "str",
"value": "PUT"
},
{
"name": "object_id",
"type": "str",
"value": "3306"
},
{
"name": "resource_id",
"type": "str",
"value": "5851"
}
],
"x": 695,
"y": 1040,
"wires": [
[
"5d8c2c55.f50524"
]
]
},
{
"id": "ee3ae218.4efd8",
"type": "subflow:1e071b74.a346dd",
"z": "2ee26e35.8449fa",
"name": "",
"env": [
{
"name": "resource_id",
"type": "str",
"value": "5850"
}
],
"x": 210,
"y": 860,
"wires": [
[
"e9fdfed3.d04b08"
]
]
},
{
"id": "b9736b53.e6e3a",
"type": "comment",
"z": "2ee26e35.8449fa",
"name": "FLOW INPUT",
"info": "",
"x": 150,
"y": 60,
"wires": []
},
{
"id": "c6a8d603.e28de8",
"type": "comment",
"z": "2ee26e35.8449fa",
"name": "FLOW OUPUT",
"info": "",
"x": 960,
"y": 60,
"wires": []
},
{
"id": "cf133017.ddeda8",
"type": "ui_switch",
"z": "2ee26e35.8449fa",
"name": "relay-2-selection",
"label": "{{msg.label}}",
"tooltip": "{{msg.tooltip}}",
"group": "18dbcafd.0bd0d5",
"order": 6,
"width": "3",
"height": "1",
"passthru": false,
"decouple": "true",
"topic": "",
"style": "",
"onvalue": "true",
"onvalueType": "bool",
"onicon": "",
"oncolor": "",
"offvalue": "false",
"offvalueType": "bool",
"officon": "",
"offcolor": "",
"x": 950,
"y": 580,
"wires": [
[
"3df94773.89eaf"
]
]
},
{
"id": "3360bfe.93785c",
"type": "ui_template",
"z": "2ee26e35.8449fa",
"group": "18dbcafd.0bd0d5",
"name": "relay-2-status",
"order": 5,
"width": "6",
"height": "1",
"format": "<!DOCTYPE html>\n<svg viewBox=\"0 0 270 40\" id=\"{{'devices-status-'+ $id}}\">\n <text x=\"0\" y=\"25\" style=\"{{'font-weight:700'}}\" >{{$deviceName}}</text>\n <image\n id=\"{{'device-icon-'+$id}}\" \n x=\"200\"\n y=\"2\"\n width=\"35px\" \n height=\"35px\"\n preserveAspectRatio=\"xMidYMin slice\"\n xlink:href=\"{{ $getImageUrl() }}\"></image>\n <circle id=\"{{'devices-status-icon-'+$id}}\" x=\"0\" y=\"0\" cx=\"265\" cy=\"20\" r=\"15\" fill=\"{{$statusColor}}\" ></circle>\n</svg>\n<script>\n(function(scope) {\n scope.$watch('msg', (msg) => {\n try{\n scope.$statusText = \"Waiting\";\n scope.$deviceName = \"\";\n scope.$statusColor = \"#ff4500\";\n scope.$getImageUrl = () => {\n const icon = scope.$deviceIcon || \"\";\n return icon;\n }\n if (msg && msg.device) {\n scope.$deviceName = msg.device.name;\n scope.$deviceIcon = msg.device.icons[0];\n if (msg && (msg.device.status === true || msg.device.status === \"true\")) {\n scope.$statusColor = \"#baff00\";\n scope.$statusText = \"Ready\";\n }\n }\n // return msg;\n } catch(error){\n return error;\n }\n \n });\n})(scope);\n</script>",
"storeOutMessages": false,
"fwdInMessages": false,
"templateScope": "local",
"x": 280,
"y": 620,
"wires": [
[]
]
},
{
"id": "3df94773.89eaf",
"type": "subflow:32f8e46a.971f8c",
"z": "2ee26e35.8449fa",
"name": "",
"env": [
{
"name": "device_name",
"type": "env",
"value": "device_name"
},
{
"name": "store_type",
"type": "str",
"value": "file"
}
],
"x": 1170,
"y": 580,
"wires": [
[
"c7ca29ec.170fd"
]
]
},
{
"id": "3e65a804.6bc7a8",
"type": "change",
"z": "2ee26e35.8449fa",
"name": "devicesSelection",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "#:(file)::devicesSelection",
"tot": "global"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 290,
"y": 580,
"wires": [
[
"a8e23408.d8c23"
]
]
},
{
"id": "c7ca29ec.170fd",
"type": "subflow:8ff67ce6.9014f",
"z": "2ee26e35.8449fa",
"name": "",
"env": [
{
"name": "label_true",
"type": "str",
"value": "Remove"
},
{
"name": "tooltip_true",
"type": "str",
"value": "Remove from device selection"
},
{
"name": "topic_true",
"type": "str",
"value": "DELETE/devicesSelection"
},
{
"name": "payload_true",
"type": "bool",
"value": "true"
},
{
"name": "label_false",
"type": "str",
"value": "Add"
},
{
"name": "tooltip_false",
"type": "str",
"value": "Add to device selection"
},
{
"name": "topic_false",
"type": "str",
"value": "POST/devicesSelection"
},
{
"name": "payload_false",
"type": "bool",
"value": "false"
}
],
"x": 730,
"y": 580,
"wires": [
[
"cf133017.ddeda8"
]
]
},
{
"id": "8935454f.3f3578",
"type": "comment",
"z": "2ee26e35.8449fa",
"name": "Device properties",
"info": "",
"x": 170,
"y": 520,
"wires": []
},
{
"id": "ae39d9c8.5b9a2",
"type": "link in",
"z": "2ee26e35.8449fa",
"name": "->filter-device",
"links": [
"4a6efc2e.622b2c",
"749d689d.d98358",
"fb957969.7809e8"
],
"x": 95,
"y": 580,
"wires": [
[
"3e65a804.6bc7a8",
"3360bfe.93785c",
"83a16a16.4153d8"
]
]
},
{
"id": "fb957969.7809e8",
"type": "link out",
"z": "2ee26e35.8449fa",
"name": "device-properties->",
"links": [
"ae39d9c8.5b9a2"
],
"x": 335,
"y": 100,
"wires": []
},
{
"id": "63d58f38.04b448",
"type": "link out",
"z": "2ee26e35.8449fa",
"name": "1/3306/1/5850",
"links": [
"a563aa2.0d976d8"
],
"x": 655,
"y": 100,
"wires": []
},
{
"id": "1c590e3b.8fe202",
"type": "link out",
"z": "2ee26e35.8449fa",
"name": "1/3306/2/5850",
"links": [],
"x": 655,
"y": 180,
"wires": []
},
{
"id": "54a0dc24.93a7ac",
"type": "link out",
"z": "2ee26e35.8449fa",
"name": "1/3306/1/5851",
"links": [
"7ee0fa4b.6be53c"
],
"x": 655,
"y": 260,
"wires": []
},
{
"id": "57010d68.8060ec",
"type": "link out",
"z": "2ee26e35.8449fa",
"name": "1/3306/2/5851",
"links": [],
"x": 655,
"y": 340,
"wires": []
},
{
"id": "12832e27.fc6972",
"type": "subflow:541e2a83.f89d2c",
"z": "2ee26e35.8449fa",
"name": "",
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"x": 260,
"y": 240,
"wires": [
[
"fb957969.7809e8"
],
[
"e844add5.3f456"
],
[
"a3a533e7.e9637"
],
[
"a840ca87.d601"
],
[
"ef3b7202.bb0d6"
],
[]
]
},
{
"id": "e844add5.3f456",
"type": "switch",
"z": "2ee26e35.8449fa",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 480,
"y": 120,
"wires": [
[
"63d58f38.04b448"
],
[
"63d58f38.04b448"
],
[],
[
"698d949a.0640ec"
]
]
},
{
"id": "a3a533e7.e9637",
"type": "switch",
"z": "2ee26e35.8449fa",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 480,
"y": 200,
"wires": [
[
"1c590e3b.8fe202"
],
[
"1c590e3b.8fe202"
],
[],
[
"82d3ecbe.583778"
]
]
},
{
"id": "a840ca87.d601",
"type": "switch",
"z": "2ee26e35.8449fa",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 480,
"y": 280,
"wires": [
[
"54a0dc24.93a7ac"
],
[
"54a0dc24.93a7ac"
],
[],
[
"15fb67f4.b91048"
]
]
},
{
"id": "ef3b7202.bb0d6",
"type": "switch",
"z": "2ee26e35.8449fa",
"name": "Method",
"property": "method",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "POST",
"vt": "str"
},
{
"t": "eq",
"v": "PUT",
"vt": "str"
},
{
"t": "eq",
"v": "GET",
"vt": "str"
},
{
"t": "eq",
"v": "HEAD",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 4,
"x": 480,
"y": 360,
"wires": [
[
"57010d68.8060ec"
],
[
"57010d68.8060ec"
],
[],
[
"31fb6de.a189912"
]
]
},
{
"id": "31fb6de.a189912",
"type": "link out",
"z": "2ee26e35.8449fa",
"name": "0/3306/2/5851",
"links": [],
"x": 655,
"y": 380,
"wires": []
},
{
"id": "15fb67f4.b91048",
"type": "link out",
"z": "2ee26e35.8449fa",
"name": "0/3306/1/5851",
"links": [
"7ee0fa4b.6be53c"
],
"x": 655,
"y": 300,
"wires": []
},
{
"id": "82d3ecbe.583778",
"type": "link out",
"z": "2ee26e35.8449fa",
"name": "0/3306/2/5850",
"links": [],
"x": 655,
"y": 220,
"wires": []
},
{
"id": "698d949a.0640ec",
"type": "link out",
"z": "2ee26e35.8449fa",
"name": "0/3306/1/5850",
"links": [
"a563aa2.0d976d8"
],
"x": 655,
"y": 140,
"wires": []
},
{
"id": "83a16a16.4153d8",
"type": "change",
"z": "2ee26e35.8449fa",
"name": "description",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "device.description",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 270,
"y": 660,
"wires": [
[
"6769490a.d5fa08"
]
]
},
{
"id": "6769490a.d5fa08",
"type": "ui_text",
"z": "2ee26e35.8449fa",
"group": "92ed92ec.2f98f8",
"order": 1,
"width": "12",
"height": "1",
"name": "description",
"label": "",
"format": "{{msg.payload || \"\" }}",
"layout": "row-left",
"x": 450,
"y": 660,
"wires": []
},
{
"id": "a8e23408.d8c23",
"type": "subflow:41c6c6f2.febed8",
"z": "2ee26e35.8449fa",
"name": "",
"env": [],
"x": 520,
"y": 580,
"wires": [
[
"c7ca29ec.170fd"
]
]
},
{
"id": "92ed92ec.2f98f8",
"type": "ui_group",
"z": "2ee26e35.8449fa",
"name": "relay-2",
"tab": "fe99d4b2.836eb",
"order": 4,
"disp": true,
"width": "12",
"collapse": true
},
{
"id": "18dbcafd.0bd0d5",
"type": "ui_group",
"z": "",
"name": "List",
"tab": "fe99d4b2.836eb",
"order": 8,
"disp": true,
"width": "9",
"collapse": true
},
{
"id": "fe99d4b2.836eb",
"type": "ui_tab",
"z": "",
"name": "devices",
"icon": "dashboard",
"order": 3,
"disabled": false,
"hidden": false
},
{
"id": "17af590f.41f4ff",
"type": "subflow",
"name": "aloes-device",
"info": "**aloes-device**\n\nFilter MQTT messages concerning the selected device. \nBuild and dispatch sensor / device models.\n\n\n`device_id` device to listen\n\n`device_name` Aloes instance host ( eg 1883, 3000, . )\n\n`debug` control debug display ( true / false ) \n\n`store_type` How to store instance ( true / false ) \n",
"category": "aloes",
"in": [
{
"x": 180,
"y": 220,
"wires": [
{
"id": "6d9bf80.8361708"
}
]
}
],
"out": [
{
"x": 600,
"y": 160,
"wires": [
{
"id": "6d9bf80.8361708",
"port": 0
}
]
},
{
"x": 600,
"y": 220,
"wires": [
{
"id": "6d9bf80.8361708",
"port": 1
}
]
},
{
"x": 600,
"y": 280,
"wires": [
{
"id": "6d9bf80.8361708",
"port": 2
}
]
}
],
"env": [
{
"name": "device_id",
"type": "str",
"value": ""
},
{
"name": "device_name",
"type": "str",
"value": ""
},
{
"name": "debug",
"type": "bool",
"value": "true"
}
],
"outputLabels": [
"Device",
"Sensor",
"Measurement"
],
"icon": "node-red/feed.png",
"status": {
"x": 620,
"y": 80,
"wires": [
{
"id": "1dffd3c6.5dd6b4",
"port": 0
}
]
}
},
{
"id": "6d9bf80.8361708",
"type": "function",
"z": "17af590f.41f4ff",
"name": "switch-msg-properties",
"func": "try {\n const debug = env.get(\"debug\");\n let deviceName = env.get(\"device_name\");\n if (!deviceName) throw new Error(\"Missing device_name variable\");\n const deviceId = env.get(\"device_id\");\n if (!deviceId) throw new Error(\"Missing device_id variable\");\n deviceName = deviceName.toLowerCase();\n if (msg.device && msg.device !== null && msg.device.id) {\n if (msg.device.id.toString() === deviceId) {\n if (msg.device.status) {\n node.status({fill:\"green\",shape:\"ring\",text:\"connected\"});\n } else {\n node.status({fill:\"red\",shape:\"ring\",text:\"disconnected\"});\n }\n if (msg.device.sensors) {\n delete msg.device.sensors;\n }\n if (debug) {\n console.log(\"set Device\", msg.device);\n const message = {topic: msg.topic, payload : msg.device};\n return [msg, null, null, message];\n }\n return [msg, null, null, null];\n }\n return [null, null, null];\n } else if (msg.sensor && msg.sensor !== null && msg.sensor.deviceId) {\n const deviceId = env.get(\"device_id\");\n if (msg.sensor.deviceId.toString() === deviceId) {\n if (debug) {\n // console.log(\"set Sensor\", msg.sensor);\n const message = {topic: msg.topic, payload : msg.sensor};\n return [null, msg, null, message];\n }\n return [null, msg, null, null];\n }\n return [null, null, null];\n } else if (msg.measurement && msg.measurement !== null && msg.measurement.deviceId) {\n const deviceId = env.get(\"device_id\");\n if (msg.measurement.deviceId === deviceId) {\n if (debug) {\n // console.log(\"set Measurement\", msg.measurement);\n const message = {topic: msg.topic, payload : msg.measurement};\n return [null, null, msg, message];\n }\n return [null, null, msg, null];\n }\n return [null, null, null, null];\n } \n throw new Error(\"No instance to parse\");\n} catch(error){\n return error;\n}\n",
"outputs": 4,
"noerr": 0,
"x": 340,
"y": 220,
"wires": [
[],
[],
[],
[
"e681b8fd.712ee"
]
]
},
{
"id": "e681b8fd.712ee",
"type": "debug",
"z": "17af590f.41f4ff",
"name": "${device_name}",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 380,
"y": 320,
"wires": []
},
{
"id": "1dffd3c6.5dd6b4",
"type": "status",
"z": "17af590f.41f4ff",
"name": "Aloes-Client status",
"scope": [
"6d9bf80.8361708"
],
"x": 250,
"y": 80,
"wires": [
[]
]
},
{
"id": "b8f66128.fc2408",
"type": "link in",
"z": "87bcccbf.ba98c",
"name": "->relay-test-interfaces",
"links": [
"589593f.4531bec",
"8c55f5a3.a16508"
],
"x": 595,
"y": 240,
"wires": [
[
"6710b9af.a2a3d"
]
]
},
{
"id": "7977091a.fdee4",
"type": "subflow:17af590f.41f4ff",
"z": "87bcccbf.ba98c",
"name": "relay-2",
"env": [
{
"name": "device_id",
"type": "str",
"value": "5c9b9fb0d0c21b6465b889e9"
},
{
"name": "device_name",
"type": "str",
"value": "relay-2"
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"x": 280,
"y": 240,
"wires": [
[
"8c55f5a3.a16508"
],
[
"8c55f5a3.a16508"
],
[
"8c55f5a3.a16508"
]
]
},
{
"id": "511f392e.da52f",
"type": "link in",
"z": "87bcccbf.ba98c",
"name": "->relay-test-in",
"links": [
"7d6dcf14.3d90c8",
"7f8ad7c.77305a8",
"af6d43bf.4a9de"
],
"x": 175,
"y": 240,
"wires": [
[
"7977091a.fdee4"
]
]
},
{
"id": "6710b9af.a2a3d",
"type": "subflow:2ee26e35.8449fa",
"z": "87bcccbf.ba98c",
"name": "",
"env": [
{
"name": "debug",
"type": "bool",
"value": "false"
},
{
"name": "device_id",
"type": "str",
"value": "5c9b9fb0d0c21b6465b889e9"
},
{
"name": "device_name",
"type": "str",
"value": "relay-2"
}
],
"x": 720,
"y": 240,
"wires": [
[
"ac245445.a3d3a8"
]
]
},
{
"id": "ac245445.a3d3a8",
"type": "link out",
"z": "87bcccbf.ba98c",
"name": "relay-test-interfaces->",
"links": [
"a447ee9d.24b2d"
],
"x": 895,
"y": 240,
"wires": []
},
{
"id": "8c55f5a3.a16508",
"type": "link out",
"z": "87bcccbf.ba98c",
"name": "relay-test-in->",
"links": [
"b8f66128.fc2408"
],
"x": 455,
"y": 240,
"wires": []
},
{
"id": "b60708fa.e84a38",
"type": "comment",
"z": "87bcccbf.ba98c",
"name": "Devices inputs",
"info": "",
"x": 240,
"y": 120,
"wires": []
},
{
"id": "5ae865db.1fe1e4",
"type": "status",
"z": "87bcccbf.ba98c",
"name": "relay status",
"scope": [
"7977091a.fdee4"
],
"x": 290,
"y": 200,
"wires": [
[
"8c55f5a3.a16508"
]
]
},
{
"id": "186dfc7f.917af4",
"type": "comment",
"z": "87bcccbf.ba98c",
"name": "Interfaces/Scenario",
"info": "",
"x": 670,
"y": 120,
"wires": []
},
{
"id": "26e97a8.a477c86",
"type": "subflow:17af590f.41f4ff",
"z": "87bcccbf.ba98c",
"name": "relay-3",
"env": [
{
"name": "device_id",
"type": "str",
"value": "5cbdaa472e66203d260968a3"
},
{
"name": "device_name",
"type": "str",
"value": "relay-3"
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"x": 280,
"y": 340,
"wires": [
[
"b12f23a4.f47a3"
],
[
"b12f23a4.f47a3"
],
[
"b12f23a4.f47a3"
]
]
},
{
"id": "a89450f3.3912e8",
"type": "link in",
"z": "87bcccbf.ba98c",
"name": "->relay-1-in",
"links": [
"7d6dcf14.3d90c8",
"7f8ad7c.77305a8",
"af6d43bf.4a9de"
],
"x": 175,
"y": 340,
"wires": [
[
"26e97a8.a477c86"
]
]
},
{
"id": "b12f23a4.f47a3",
"type": "link out",
"z": "87bcccbf.ba98c",
"name": "relay-1-in->",
"links": [
"94299316.53f558"
],
"x": 455,
"y": 340,
"wires": []
},
{
"id": "6c9e0758.adb5b8",
"type": "status",
"z": "87bcccbf.ba98c",
"name": "relay-3 status",
"scope": [
"26e97a8.a477c86"
],
"x": 290,
"y": 300,
"wires": [
[
"b12f23a4.f47a3"
]
]
},
{
"id": "ce6e1757.c78e7",
"type": "subflow:d7a593e6.9b06f",
"z": "87bcccbf.ba98c",
"name": "",
"env": [
{
"name": "device_id",
"type": "str",
"value": "5cbdaa472e66203d260968a3"
},
{
"name": "device_name",
"type": "str",
"value": "relay-3"
}
],
"x": 720,
"y": 340,
"wires": [
[
"6b3293d0.e6849c"
]
]
},
{
"id": "94299316.53f558",
"type": "link in",
"z": "87bcccbf.ba98c",
"name": "->relay-1-interfaces",
"links": [
"589593f.4531bec",
"b12f23a4.f47a3"
],
"x": 595,
"y": 340,
"wires": [
[
"ce6e1757.c78e7"
]
]
},
{
"id": "6b3293d0.e6849c",
"type": "link out",
"z": "87bcccbf.ba98c",
"name": "relay-1-interfaces->",
"links": [
"a447ee9d.24b2d"
],
"x": 895,
"y": 340,
"wires": []
},
{
"id": "810eb238.8cf7e",
"type": "subflow:17af590f.41f4ff",
"z": "87bcccbf.ba98c",
"name": "rfid-scanner-2",
"env": [
{
"name": "device_id",
"type": "str",
"value": "5d3f42f5a023bf21a2b19fcb"
},
{
"name": "device_name",
"type": "str",
"value": "rfid-scanner-2"
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"x": 300,
"y": 520,
"wires": [
[
"cc08f382.4796b"
],
[
"cc08f382.4796b"
],
[]
]
},
{
"id": "ac485d96.b7d278",
"type": "link in",
"z": "87bcccbf.ba98c",
"name": "->rfid-scanner-2-in",
"links": [
"7d6dcf14.3d90c8",
"7f8ad7c.77305a8",
"af6d43bf.4a9de"
],
"x": 175,
"y": 520,
"wires": [
[
"810eb238.8cf7e"
]
]
},
{
"id": "cc08f382.4796b",
"type": "link out",
"z": "87bcccbf.ba98c",
"name": "rfid-scanner-2-in->",
"links": [
"decdf8ad.54bb8"
],
"x": 475,
"y": 520,
"wires": []
},
{
"id": "eec7f2b1.a6b4d8",
"type": "status",
"z": "87bcccbf.ba98c",
"name": "rfid-scanner-2 status",
"scope": [
"810eb238.8cf7e"
],
"x": 280,
"y": 480,
"wires": [
[
"cc08f382.4796b"
]
]
},
{
"id": "6374fd11.ba6cc4",
"type": "subflow:84450db6.23247",
"z": "87bcccbf.ba98c",
"name": "",
"env": [
{
"name": "device_id",
"type": "str",
"value": "5d3f42f5a023bf21a2b19fcb"
},
{
"name": "device_name",
"type": "str",
"value": "rfid-scanner-2"
}
],
"x": 740,
"y": 520,
"wires": [
[
"f600a48b.9b1d88"
]
]
},
{
"id": "decdf8ad.54bb8",
"type": "link in",
"z": "87bcccbf.ba98c",
"name": "->rfid-scanner-2-interfaces",
"links": [
"589593f.4531bec",
"cc08f382.4796b"
],
"x": 595,
"y": 520,
"wires": [
[
"6374fd11.ba6cc4"
]
]
},
{
"id": "f600a48b.9b1d88",
"type": "link out",
"z": "87bcccbf.ba98c",
"name": "rfid-scanner-2-interfaces->",
"links": [
"a447ee9d.24b2d"
],
"x": 895,
"y": 520,
"wires": []
},
{
"id": "47814936.371de",
"type": "subflow:17af590f.41f4ff",
"z": "87bcccbf.ba98c",
"name": "camera-2",
"env": [
{
"name": "device_id",
"type": "str",
"value": "5c9b8ae8e099905878e93943"
},
{
"name": "device_name",
"type": "str",
"value": "camera-2"
},
{
"name": "debug",
"type": "bool",
"value": "false"
}
],
"x": 280,
"y": 660,
"wires": [
[
"e5ec9d89.dedb88"
],
[
"e5ec9d89.dedb88"
],
[
"e5ec9d89.dedb88"
]
]
},
{
"id": "4df484f0.fb1624",
"type": "link in",
"z": "87bcccbf.ba98c",
"name": "->camera-2-in",
"links": [
"7d6dcf14.3d90c8",
"7f8ad7c.77305a8",
"af6d43bf.4a9de"
],
"x": 175,
"y": 660,
"wires": [
[
"47814936.371de"
]
]
},
{
"id": "8c1cacf2.ae1178",
"type": "subflow:35404dde.e62b92",
"z": "87bcccbf.ba98c",
"name": "",
"env": [
{
"name": "device_id",
"type": "str",
"value": "5c9b8ae8e099905878e93943"
},
{
"name": "device_name",
"type": "str",
"value": "camera-2"
}
],
"x": 720,
"y": 660,
"wires": [
[
"8e004967.1d3c5"
]
]
},
{
"id": "a311780b.43fc88",
"type": "link in",
"z": "87bcccbf.ba98c",
"name": "->camera-2-interfaces",
"links": [
"589593f.4531bec",
"e5ec9d89.dedb88"
],
"x": 595,
"y": 660,
"wires": [
[
"8c1cacf2.ae1178"
]
]
},
{
"id": "8e004967.1d3c5",
"type": "link out",
"z": "87bcccbf.ba98c",
"name": "camera-2-interfaces->",
"links": [
"a447ee9d.24b2d"
],
"x": 895,
"y": 660,
"wires": []
},
{
"id": "e5ec9d89.dedb88",
"type": "link out",
"z": "87bcccbf.ba98c",
"name": "camera-2-in->",
"links": [
"a311780b.43fc88"
],
"x": 455,
"y": 660,
"wires": []
},
{
"id": "6095813b.5ae3a8",
"type": "status",
"z": "87bcccbf.ba98c",
"name": "camera-2 status",
"scope": [
"47814936.371de"
],
"x": 260,
"y": 620,
"wires": [
[
"e5ec9d89.dedb88"
]
]
}
]
@getlarge
Copy link
Author

Import Aloes devices, implement interfaces and simple IOTA interactions.
( Address generation per device, transaction allowing camera snapshot, transaction after RFID reading, seed generation and association with deviceIds... )

Prerequisites :

  • Your own instance of device-manager or an account on aloes.io
  • A machine running node-red-bridge-iota configured to your Aloes account, and IOTA provider + initial seed
  • 3 devices registered on your Aloes account : flashed with arduino-device-mqtt library

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment