From c186f27bfbb7a831b3cfbddecbff5c0460d02c58 Mon Sep 17 00:00:00 2001 From: waelkh12 <waelkhlifi12@gmail.com> Date: Fri, 19 Apr 2024 01:28:19 +0100 Subject: [PATCH] added_access_control_interface --- zigbee_node_red.json | 899 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 898 insertions(+), 1 deletion(-) diff --git a/zigbee_node_red.json b/zigbee_node_red.json index 246092b..049aeb2 100644 --- a/zigbee_node_red.json +++ b/zigbee_node_red.json @@ -7,6 +7,14 @@ "info": "", "env": [] }, + { + "id": "a739aed4431ae770", + "type": "tab", + "label": "Flow 1", + "disabled": false, + "info": "", + "env": [] + }, { "id": "9355c4bbb1adc9e0", "type": "mqtt-broker", @@ -289,7 +297,7 @@ "delayToInit": 1000, "delayToClose": 200, "serverShutdownTimeout": 100, - "addressSpaceScript": "function constructAlarmAddressSpace(server, addressSpace, eventObjects, done) {\n // server = the created node-opcua server\n // addressSpace = address space of the node-opcua server\n // eventObjects = add event variables here to hold them in memory from this script\n\n // internal sandbox objects are:\n // node = the compact server node,\n // coreServer = core compact server object for debug and access to NodeOPCUA\n // this.sandboxNodeContext = node context node-red\n // this.sandboxFlowContext = flow context node-red\n // this.sandboxGlobalContext = global context node-red\n // this.sandboxEnv = env variables\n // timeout and interval functions as expected from nodejs\n\n \n const opcua = coreServer.choreCompact.opcua;\n const LocalizedText = opcua.LocalizedText;\n const namespace = addressSpace.getOwnNamespace();\n\n const Variant = opcua.Variant;\n const DataType = opcua.DataType;\n const DataValue = opcua.DataValue;\n\n var flexServerInternals = this;\n\n \n const rootFolder = addressSpace.findNode(\"RootFolder\");\n\n this.sandboxFlowContext.set(\"Humidity\", false);\n this.sandboxFlowContext.set(\"Temperature\", false);\n this.sandboxFlowContext.set(\"critical_temperature\", false);\n this.sandboxFlowContext.set(\"critical_humidity\", false);\n\n const sensor_Data = namespace.addFolder(rootFolder.objects, {\n \"browseName\": \"Sensor_data\"\n });\n const temperature = namespace.addFolder(sensor_Data, {\n \"browseName\": \"temperature\"\n });\n const humidity = namespace.addFolder(sensor_Data, {\n \"browseName\": \"humidity\"\n });\n const temperature_float = namespace.addFolder(temperature, {\n \"browseName\": \"Float_C\"\n });\n const humidity_float = namespace.addFolder(humidity, {\n \"browseName\": \"humidity_%\"\n });\n const tempCritical = namespace.addFolder(sensor_Data, {\n \"browseName\": \"Temp_critical\"\n });\n const humidityCritical = namespace.addFolder(sensor_Data, {\n \"browseName\": \"Humidity_critical\"\n });\n const temperature_var = namespace.addVariable({\n \"organizedBy\": temperature_float,\n \"browseName\": \"temperature\",\n \"nodeId\": \"ns=1;s=Temperature_value\",\n \"dataType\": \"Double\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Double,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"Temperature\")\n });\n },\n \"set\": function (Variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"Temperature\",\n Variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n const humidity_var = namespace.addVariable({\n \"organizedBy\": humidity_float,\n \"browseName\": \"Humidity\",\n \"nodeId\": \"ns=1;s=Humidity_value\",\n \"dataType\": \"Double\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Double,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"Humidity\")\n });\n },\n \"set\": function (Variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"Humidity\",\n Variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n const temperatureCritical = namespace.addVariable({\n \"organizedBy\": tempCritical,\n \"browseName\": \"Value\",\n \"nodeId\": \"ns=1;s=Temp_critical_value\",\n \"dataType\": \"Boolean\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Boolean,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"critical_temperature\")\n });\n },\n \"set\": function (variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"critical_temperature\",\n variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n\n const humidityCrit = namespace.addVariable({\n \"organizedBy\": humidityCritical,\n \"browseName\": \"Value\",\n \"nodeId\": \"ns=1;s=Humidity_critical_value\",\n \"dataType\": \"Boolean\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Boolean,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"critical_humidity\")\n });\n },\n \"set\": function (variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"critical_humidity\",\n variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n\n \n done();\n}", + "addressSpaceScript": "function constructAlarmAddressSpace(server, addressSpace, eventObjects, done) {\n // server = the created node-opcua server\n // addressSpace = address space of the node-opcua server\n // eventObjects = add event variables here to hold them in memory from this script\n\n // internal sandbox objects are:\n // node = the compact server node,\n // coreServer = core compact server object for debug and access to NodeOPCUA\n // this.sandboxNodeContext = node context node-red\n // this.sandboxFlowContext = flow context node-red\n // this.sandboxGlobalContext = global context node-red\n // this.sandboxEnv = env variables\n // timeout and interval functions as expected from nodejs\n\n \n const opcua = coreServer.choreCompact.opcua;\n const LocalizedText = opcua.LocalizedText;\n const namespace = addressSpace.getOwnNamespace();\n\n const Variant = opcua.Variant;\n const DataType = opcua.DataType;\n const DataValue = opcua.DataValue;\n\n var flexServerInternals = this;\n\n \n const rootFolder = addressSpace.findNode(\"RootFolder\");\n\n this.sandboxFlowContext.set(\"Humidity\", false);\n this.sandboxFlowContext.set(\"Temperature\", false);\n this.sandboxFlowContext.set(\"critical_temperature\", false);\n this.sandboxFlowContext.set(\"critical_humidity\", false);\n this.sandboxFlowContext.set(\"access\", false);\n\n const sensor_Data = namespace.addFolder(rootFolder.objects, {\n \"browseName\": \"Sensor_data\"\n });\n const access_control = namespace.addFolder(rootFolder.objects, {\n \"browseName\": \"access_control\"\n });\n const access = namespace.addFolder(access_control, {\n \"browseName\": \"access_event\"\n });\n const temperature = namespace.addFolder(sensor_Data, {\n \"browseName\": \"temperature\"\n });\n const humidity = namespace.addFolder(sensor_Data, {\n \"browseName\": \"humidity\"\n });\n const temperature_float = namespace.addFolder(temperature, {\n \"browseName\": \"Float_C\"\n });\n const humidity_float = namespace.addFolder(humidity, {\n \"browseName\": \"humidity_%\"\n });\n const tempCritical = namespace.addFolder(sensor_Data, {\n \"browseName\": \"Temp_critical\"\n });\n const humidityCritical = namespace.addFolder(sensor_Data, {\n \"browseName\": \"Humidity_critical\"\n });\n const temperature_var = namespace.addVariable({\n \"organizedBy\": temperature_float,\n \"browseName\": \"temperature\",\n \"nodeId\": \"ns=1;s=Temperature_value\",\n \"dataType\": \"Double\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Double,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"Temperature\")\n });\n },\n \"set\": function (Variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"Temperature\",\n Variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n const humidity_var = namespace.addVariable({\n \"organizedBy\": humidity_float,\n \"browseName\": \"Humidity\",\n \"nodeId\": \"ns=1;s=Humidity_value\",\n \"dataType\": \"Double\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Double,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"Humidity\")\n });\n },\n \"set\": function (Variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"Humidity\",\n Variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n const temperatureCritical = namespace.addVariable({\n \"organizedBy\": tempCritical,\n \"browseName\": \"Value\",\n \"nodeId\": \"ns=1;s=Temp_critical_value\",\n \"dataType\": \"Boolean\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Boolean,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"critical_temperature\")\n });\n },\n \"set\": function (variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"critical_temperature\",\n variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n\n const humidityCrit = namespace.addVariable({\n \"organizedBy\": humidityCritical,\n \"browseName\": \"Value\",\n \"nodeId\": \"ns=1;s=Humidity_critical_value\",\n \"dataType\": \"Boolean\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Boolean,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"critical_humidity\")\n });\n },\n \"set\": function (variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"critical_humidity\",\n variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n const accessevent= namespace.addVariable({\n \"organizedBy\": access_control,\n \"browseName\": \"Value\",\n \"nodeId\": \"ns=1;s=accessevent\",\n \"dataType\": \"Boolean\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Boolean,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"access\")\n });\n },\n \"set\": function (variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"access\",\n variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n\n \n done();\n}", "x": 540, "y": 1120, "wires": [] @@ -642,5 +650,894 @@ "x": 610, "y": 1260, "wires": [] + }, + { + "id": "c09bba319746468b", + "type": "comment", + "z": "2df1dfd158b253ed", + "name": "access control", + "info": "", + "x": 70, + "y": 1360, + "wires": [] + }, + { + "id": "12212c1cf0a810d6", + "type": "pythonshell in", + "z": "2df1dfd158b253ed", + "name": "acces_control", + "pyfile": "/home/waelkh12/Desktop/tf_lite_face_reco/facial_recognition_for_access_control/test_model/use_tflite.py", + "virtualenv": "", + "continuous": false, + "stdInData": false, + "x": 500, + "y": 1520, + "wires": [ + [ + "c79076b1c216d02b", + "5604778b506f58f6" + ] + ] + }, + { + "id": "9e4e088f5a843a62", + "type": "mqtt in", + "z": "2df1dfd158b253ed", + "name": "", + "topic": "command_access_control", + "qos": "2", + "datatype": "auto-detect", + "broker": "ff246c28cc0fa0af", + "nl": false, + "rap": true, + "rh": 0, + "inputs": 0, + "x": 130, + "y": 1460, + "wires": [ + [ + "f171cea0b358fd4a", + "0e3967dcd9d12ed9" + ] + ] + }, + { + "id": "f171cea0b358fd4a", + "type": "debug", + "z": "2df1dfd158b253ed", + "name": "debug 4", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 300, + "y": 1560, + "wires": [] + }, + { + "id": "c79076b1c216d02b", + "type": "debug", + "z": "2df1dfd158b253ed", + "name": "debug 5", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 780, + "y": 1460, + "wires": [] + }, + { + "id": "0e3967dcd9d12ed9", + "type": "function", + "z": "2df1dfd158b253ed", + "name": "function 1", + "func": "if (msg.payload= true) {\nreturn msg;\n}", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 300, + "y": 1380, + "wires": [ + [ + "12212c1cf0a810d6" + ] + ] + }, + { + "id": "5604778b506f58f6", + "type": "function", + "z": "2df1dfd158b253ed", + "name": "function 2", + "func": "global.set(\"access\", msg.payload);\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 600, + "y": 1400, + "wires": [ + [ + "5ba7cdd1a9ee0349", + "640ece0026ef75ee" + ] + ] + }, + { + "id": "5ba7cdd1a9ee0349", + "type": "debug", + "z": "2df1dfd158b253ed", + "name": "debug 6", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 980, + "y": 1440, + "wires": [] + }, + { + "id": "640ece0026ef75ee", + "type": "mqtt out", + "z": "2df1dfd158b253ed", + "name": "", + "topic": "command_access_control", + "qos": "", + "retain": "", + "respTopic": "", + "contentType": "", + "userProps": "", + "correl": "", + "expiry": "", + "broker": "ff246c28cc0fa0af", + "x": 930, + "y": 1400, + "wires": [] + }, + { + "id": "7271c8bad7f9f8bb", + "type": "pythonshell in", + "z": "a739aed4431ae770", + "name": "humidity", + "pyfile": "/home/waelkh12/ble_esp32.py", + "virtualenv": "", + "continuous": true, + "stdInData": false, + "x": 60, + "y": 240, + "wires": [ + [ + "2bc1e9f386394f40", + "e0e8f53cbdb2a889", + "a87c7c60579e0348" + ] + ] + }, + { + "id": "2bc1e9f386394f40", + "type": "debug", + "z": "a739aed4431ae770", + "name": "debug 1", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 260, + "y": 260, + "wires": [] + }, + { + "id": "e0e8f53cbdb2a889", + "type": "string", + "z": "a739aed4431ae770", + "name": "", + "methods": [ + { + "name": "between", + "params": [ + { + "type": "str", + "value": "temp" + }, + { + "type": "str", + "value": "\\x" + } + ] + } + ], + "prop": "payload", + "propout": "payload", + "object": "msg", + "objectout": "msg", + "x": 290, + "y": 140, + "wires": [ + [ + "30b02c7a6d0c6eba", + "40861ba0a138617e" + ] + ] + }, + { + "id": "30b02c7a6d0c6eba", + "type": "debug", + "z": "a739aed4431ae770", + "name": "debug 2", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 460, + "y": 140, + "wires": [] + }, + { + "id": "a87c7c60579e0348", + "type": "string", + "z": "a739aed4431ae770", + "name": "", + "methods": [ + { + "name": "between", + "params": [ + { + "type": "str", + "value": "temp 19.30 \\xc2\\xb0C\\x00\\x00\\x00\\x00\\x00\\x00' b'Humidity " + }, + { + "type": "str", + "value": "%\\x" + } + ] + } + ], + "prop": "payload", + "propout": "payload", + "object": "msg", + "objectout": "msg", + "x": 270, + "y": 340, + "wires": [ + [ + "44e49f75fcfd083e", + "2b6c0703bd29503e" + ] + ] + }, + { + "id": "44e49f75fcfd083e", + "type": "debug", + "z": "a739aed4431ae770", + "name": "debug 3", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 460, + "y": 300, + "wires": [] + }, + { + "id": "2b7b3343f636e787", + "type": "debug", + "z": "a739aed4431ae770", + "name": "temperature_global_variable", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 1040, + "y": 160, + "wires": [] + }, + { + "id": "3e3d79487829c8a9", + "type": "function", + "z": "a739aed4431ae770", + "name": "set temperature as global variable", + "func": "global.set(\"temperature\", msg.payload);\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 540, + "y": 240, + "wires": [ + [ + "2b7b3343f636e787" + ] + ] + }, + { + "id": "40861ba0a138617e", + "type": "function", + "z": "a739aed4431ae770", + "name": "Convert temperature to number", + "func": "msg.payload = parseFloat(msg.payload); // Convert string to float\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 510, + "y": 180, + "wires": [ + [ + "3e3d79487829c8a9" + ] + ] + }, + { + "id": "2b6c0703bd29503e", + "type": "function", + "z": "a739aed4431ae770", + "name": "convert humidity to a number", + "func": "msg.payload = parseFloat(msg.payload); // Convert string to float\nreturn msg;\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 460, + "y": 340, + "wires": [ + [ + "21702e3db56db730" + ] + ] + }, + { + "id": "21702e3db56db730", + "type": "function", + "z": "a739aed4431ae770", + "name": "set humidity as global variable", + "func": "global.set(\"humidity\", msg.payload);\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 710, + "y": 340, + "wires": [ + [ + "c128d68db5fbd2af" + ] + ] + }, + { + "id": "c128d68db5fbd2af", + "type": "debug", + "z": "a739aed4431ae770", + "name": "humidity_global_variable", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 950, + "y": 340, + "wires": [] + }, + { + "id": "524aab8b88fb4f61", + "type": "inject", + "z": "a739aed4431ae770", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "2", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 270, + "y": 1020, + "wires": [ + [ + "387bb6928892b3c9" + ] + ] + }, + { + "id": "387bb6928892b3c9", + "type": "function", + "z": "a739aed4431ae770", + "name": "Get global variables", + "func": "flow.set('Temperature', global.get(\"temperature\"));\nflow.set('Humidity', global.get(\"humidity\"));\nflow.set('tempecriticalvl', global.get(\"critical_temperature\"))\nflow.set('humiditycriticalvl', global.get(\"critical_humditiy\"))\nflow.set('access', global.get(\"access\"))\n\nmsg.payload = [\n\nflow.get('Temperature'),\nflow.get('Humidity'),\nflow.get('tempecriticalvl'),\nflow.get('humiditycriticalvl'),\nflow.get('access')\n];\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 480, + "y": 1020, + "wires": [ + [ + "94fba5bdf2c6d102" + ] + ] + }, + { + "id": "94fba5bdf2c6d102", + "type": "debug", + "z": "a739aed4431ae770", + "name": "global variables array", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 740, + "y": 1020, + "wires": [] + }, + { + "id": "80c7f5375728fde4", + "type": "opcua-compact-server", + "z": "a739aed4431ae770", + "port": "4840", + "endpoint": "", + "productUri": "", + "acceptExternalCommands": true, + "maxAllowedSessionNumber": 10, + "maxConnectionsPerEndpoint": 10, + "maxAllowedSubscriptionNumber": 100, + "alternateHostname": "", + "name": "", + "showStatusActivities": true, + "showErrors": true, + "allowAnonymous": true, + "individualCerts": false, + "isAuditing": false, + "serverDiscovery": true, + "users": [], + "xmlsetsOPCUA": [], + "publicCertificateFile": "", + "privateCertificateFile": "", + "registerServerMethod": "1", + "discoveryServerEndpointUrl": "opc.tcp://192.168.1.105:4840", + "capabilitiesForMDNS": "", + "maxNodesPerRead": 1000, + "maxNodesPerWrite": 1000, + "maxNodesPerHistoryReadData": 100, + "maxNodesPerBrowse": 3000, + "maxBrowseContinuationPoints": 10, + "maxHistoryContinuationPoints": 10, + "delayToInit": 1000, + "delayToClose": 200, + "serverShutdownTimeout": 100, + "addressSpaceScript": "function constructAlarmAddressSpace(server, addressSpace, eventObjects, done) {\n // server = the created node-opcua server\n // addressSpace = address space of the node-opcua server\n // eventObjects = add event variables here to hold them in memory from this script\n\n // internal sandbox objects are:\n // node = the compact server node,\n // coreServer = core compact server object for debug and access to NodeOPCUA\n // this.sandboxNodeContext = node context node-red\n // this.sandboxFlowContext = flow context node-red\n // this.sandboxGlobalContext = global context node-red\n // this.sandboxEnv = env variables\n // timeout and interval functions as expected from nodejs\n\n \n const opcua = coreServer.choreCompact.opcua;\n const LocalizedText = opcua.LocalizedText;\n const namespace = addressSpace.getOwnNamespace();\n\n const Variant = opcua.Variant;\n const DataType = opcua.DataType;\n const DataValue = opcua.DataValue;\n\n var flexServerInternals = this;\n\n \n const rootFolder = addressSpace.findNode(\"RootFolder\");\n\n this.sandboxFlowContext.set(\"Humidity\", false);\n this.sandboxFlowContext.set(\"Temperature\", false);\n this.sandboxFlowContext.set(\"critical_temperature\", false);\n this.sandboxFlowContext.set(\"critical_humidity\", false);\n this.sandboxFlowContext.set(\"access\", false);\n\n const sensor_Data = namespace.addFolder(rootFolder.objects, {\n \"browseName\": \"Sensor_data\"\n });\n const access_control = namespace.addFolder(rootFolder.objects, {\n \"browseName\": \"access_control\"\n });\n const access = namespace.addFolder(access_control, {\n \"browseName\": \"access_event\"\n });\n const temperature = namespace.addFolder(sensor_Data, {\n \"browseName\": \"temperature\"\n });\n const humidity = namespace.addFolder(sensor_Data, {\n \"browseName\": \"humidity\"\n });\n const temperature_float = namespace.addFolder(temperature, {\n \"browseName\": \"Float_C\"\n });\n const humidity_float = namespace.addFolder(humidity, {\n \"browseName\": \"humidity_%\"\n });\n const tempCritical = namespace.addFolder(sensor_Data, {\n \"browseName\": \"Temp_critical\"\n });\n const humidityCritical = namespace.addFolder(sensor_Data, {\n \"browseName\": \"Humidity_critical\"\n });\n const temperature_var = namespace.addVariable({\n \"organizedBy\": temperature_float,\n \"browseName\": \"temperature\",\n \"nodeId\": \"ns=1;s=Temperature_value\",\n \"dataType\": \"Double\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Double,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"Temperature\")\n });\n },\n \"set\": function (Variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"Temperature\",\n Variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n const humidity_var = namespace.addVariable({\n \"organizedBy\": humidity_float,\n \"browseName\": \"Humidity\",\n \"nodeId\": \"ns=1;s=Humidity_value\",\n \"dataType\": \"Double\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Double,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"Humidity\")\n });\n },\n \"set\": function (Variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"Humidity\",\n Variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n const temperatureCritical = namespace.addVariable({\n \"organizedBy\": tempCritical,\n \"browseName\": \"Value\",\n \"nodeId\": \"ns=1;s=Temp_critical_value\",\n \"dataType\": \"Boolean\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Boolean,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"critical_temperature\")\n });\n },\n \"set\": function (variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"critical_temperature\",\n variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n\n const humidityCrit = namespace.addVariable({\n \"organizedBy\": humidityCritical,\n \"browseName\": \"Value\",\n \"nodeId\": \"ns=1;s=Humidity_critical_value\",\n \"dataType\": \"Boolean\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Boolean,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"critical_humidity\")\n });\n },\n \"set\": function (variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"critical_humidity\",\n variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n const accessevent= namespace.addVariable({\n \"organizedBy\": access_control,\n \"browseName\": \"Value\",\n \"nodeId\": \"ns=1;s=accessevent\",\n \"dataType\": \"Boolean\",\n \"value\": {\n \"get\": function () {\n return new Variant({\n \"dataType\": DataType.Boolean,\n \"value\": flexServerInternals.sandboxFlowContext.get(\"access\")\n });\n },\n \"set\": function (variant) {\n flexServerInternals.sandboxFlowContext.set(\n \"access\",\n variant.value\n );\n return opcua.StatusCodes.Good;\n }\n }\n });\n\n \n done();\n}", + "x": 540, + "y": 1120, + "wires": [] + }, + { + "id": "5d233b04d07eb396", + "type": "function", + "z": "a739aed4431ae770", + "name": "Check Temperature and Humidity", + "func": "// Define the acceptable range for temperature and humidity\nconst minTemperature = 10; // Minimum temperature\nconst maxTemperature = 20; // Maximum temperature\nconst criticatemp = 20; // critical temperature \nconst minHumidity = 30; // Minimum humidity\nconst maxHumidity = 40; // Maximum humidity\nconst critichumidity =80; // critical value for humidity\n// Get the incoming message payload\nvar temperature = global.get('temperature'); // Get temperature from global context\nvar humidity = global.get('humidity'); // Get humidity from global context\n// set global variables that can be used by opc_server\n\n\n// Initialize payload as a JSON object\nvar data = {\n timestamp: Date.now(),\n temperature: temperature,\n humidity: humidity,\n criticalhumidity : true,\n criticaltemp : false,\n temperatureEvent: \"\",\n humidityEvent: \"\",\n turnAC: false // Initialize turn AC variable\n};\n\n\n// Check if temperature is within the acceptable range\nif (temperature < minTemperature) {\n // Temperature is below the acceptable range\n data.temperatureEvent = \"Below Min\";\n} else if (temperature > maxTemperature) {\n // Temperature is above the acceptable range\n data.temperatureEvent = \"Above Max\";\n \n}\nelse if (temperature > criticatemp) {\n // Humidity is above the acceptable range\n data.criticaltemp= true;\n }\nelse {\n msg.payload.temperatureEvent = \"No action\"\n }\n// Check if humidity is within the acceptable range\nif (humidity < minHumidity) {\n // Humidity is below the acceptable range\n data.humidityEvent = \"Below Min\";\n} else if (humidity > maxHumidity) {\n // Humidity is above the acceptable range\n data.humidityEvent = \"Above Max\";\n }\n \n\nelse {\n data.humidityEvent = \"No action\"\n }\n\n// Set turn AC variable based on conditions\nif (data.temperatureEvent === \"Above Max\" || data.humidityEvent === \"Above Max\" || data.criticaltemp==true) {\n data.turnAC = true; // Turn on AC\n} else {\n data.turnAC = false; // Turn off AC\n}\n\n\n\n// Return message\nreturn {payload: data};", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 340, + "y": 660, + "wires": [ + [ + "115f17ea2091246b", + "8c434f9651b364db", + "d3468c97c46f07a4", + "b821c05899a164d3", + "845288bb732a3b8b" + ] + ] + }, + { + "id": "115f17ea2091246b", + "type": "csv", + "z": "a739aed4431ae770", + "name": "", + "sep": ",", + "hdrin": true, + "hdrout": "", + "multi": "one", + "ret": "\\n", + "temp": "timestamp,temperature,humidity,temperatureEvent,humidityEvent,turnAC", + "skip": "0", + "strings": true, + "include_empty_strings": false, + "include_null_values": false, + "x": 550, + "y": 660, + "wires": [ + [ + "47076c7b58833eb1" + ] + ] + }, + { + "id": "47076c7b58833eb1", + "type": "file", + "z": "a739aed4431ae770", + "d": true, + "name": "", + "filename": "C:\\Users\\waelk\\Desktop\\test.csv", + "filenameType": "str", + "appendNewline": true, + "createDir": false, + "overwriteFile": "false", + "encoding": "none", + "x": 780, + "y": 660, + "wires": [ + [] + ] + }, + { + "id": "482170d93cfc8a7e", + "type": "inject", + "z": "a739aed4431ae770", + "name": "Simulate Data", + "props": [ + { + "p": "payload" + } + ], + "repeat": "5", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 100, + "y": 660, + "wires": [ + [ + "5d233b04d07eb396" + ] + ] + }, + { + "id": "8c434f9651b364db", + "type": "debug", + "z": "a739aed4431ae770", + "name": "object containing_data_and_events", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 680, + "y": 740, + "wires": [] + }, + { + "id": "1967961443f34779", + "type": "comment", + "z": "a739aed4431ae770", + "name": "sending notifications to2", + "info": "", + "x": 100, + "y": 740, + "wires": [] + }, + { + "id": "d3468c97c46f07a4", + "type": "function", + "z": "a739aed4431ae770", + "name": "check_critical_temperature_trigger", + "func": "var inputObject = msg.payload;\n\nvar criticalTemperature = inputObject.criticaltemp;\nvar criticalHumidity = inputObject.criticalhumidity;\n\nif (criticalTemperature || criticalHumidity ) {\n // If either critical temperature or critical humidity is true\n msg.payload = \"Critical temperature or humidity condition is met.\";\n return msg;\n}\n", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 320, + "y": 820, + "wires": [ + [ + "b7213d4dd0e06ca2", + "db26524b32c2d7e8" + ] + ] + }, + { + "id": "b7213d4dd0e06ca2", + "type": "debug", + "z": "a739aed4431ae770", + "name": "trigger_conditions", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 790, + "y": 820, + "wires": [] + }, + { + "id": "db26524b32c2d7e8", + "type": "e-mail", + "z": "a739aed4431ae770", + "server": "mail.protonmail.ch", + "port": "1143", + "authtype": "BASIC", + "saslformat": true, + "token": "oauth2Response.access_token", + "secure": true, + "tls": true, + "name": "noderedopc@proton.me", + "dname": "notification_temperature", + "x": 610, + "y": 900, + "wires": [] + }, + { + "id": "2e24d6986384653d", + "type": "comment", + "z": "a739aed4431ae770", + "name": "OPC_UA_SERVER", + "info": "", + "x": 90, + "y": 960, + "wires": [] + }, + { + "id": "865c6bbd47c0a540", + "type": "comment", + "z": "a739aed4431ae770", + "name": "LOGIC_ENGINE", + "info": "", + "x": 80, + "y": 600, + "wires": [] + }, + { + "id": "b821c05899a164d3", + "type": "function", + "z": "a739aed4431ae770", + "name": "set temperature event as global var", + "func": "msg.payload= msg.payload.criticaltemp;\nglobal.set(\"critical_temperature\", msg.payload);\n\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 620, + "y": 560, + "wires": [ + [ + "b54181f525c450a6" + ] + ] + }, + { + "id": "b54181f525c450a6", + "type": "debug", + "z": "a739aed4431ae770", + "name": "temp_event", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 840, + "y": 560, + "wires": [] + }, + { + "id": "845288bb732a3b8b", + "type": "function", + "z": "a739aed4431ae770", + "name": "set humidity event as global var", + "func": "msg.payload= msg.payload.criticalhumidity;\nglobal.set(\"critical_humidity\", msg.payload);\n\nreturn msg;\nreturn msg;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 640, + "y": 480, + "wires": [ + [ + "1688460797640cd9" + ] + ] + }, + { + "id": "1688460797640cd9", + "type": "debug", + "z": "a739aed4431ae770", + "name": "humd_event", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 850, + "y": 480, + "wires": [] + }, + { + "id": "ef5ad012504bcab2", + "type": "comment", + "z": "a739aed4431ae770", + "name": "mqtt interface", + "info": "", + "x": 70, + "y": 1200, + "wires": [] + }, + { + "id": "99be4ba0adb14297", + "type": "inject", + "z": "a739aed4431ae770", + "name": "Simulate Data", + "props": [ + { + "p": "payload" + } + ], + "repeat": "5", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 100, + "y": 1260, + "wires": [ + [ + "394910826d2fbaf5" + ] + ] + }, + { + "id": "394910826d2fbaf5", + "type": "function", + "z": "a739aed4431ae770", + "name": "Check Temperature and Humidity", + "func": "// Define the acceptable range for temperature and humidity\nconst minTemperature = 10; // Minimum temperature\nconst maxTemperature = 20; // Maximum temperature\nconst criticatemp = 20; // critical temperature \nconst minHumidity = 30; // Minimum humidity\nconst maxHumidity = 40; // Maximum humidity\nconst critichumidity =80; // critical value for humidity\n// Get the incoming message payload\nvar temperature = global.get('temperature'); // Get temperature from global context\nvar humidity = global.get('humidity'); // Get humidity from global context\n// set global variables that can be used by opc_server\n\n\n// Initialize payload as a JSON object\nvar data = {\n timestamp: Date.now(),\n temperature: temperature,\n humidity: humidity,\n criticalhumidity : false,\n criticaltemp : false,\n temperatureEvent: \"\",\n humidityEvent: \"\",\n turnAC: false // Initialize turn AC variable\n};\n\n\n// Check if temperature is within the acceptable range\nif (temperature < minTemperature) {\n // Temperature is below the acceptable range\n data.temperatureEvent = \"Below Min\";\n} else if (temperature > maxTemperature) {\n // Temperature is above the acceptable range\n data.temperatureEvent = \"Above Max\";\n \n}\nelse if (temperature > criticatemp) {\n // Humidity is above the acceptable range\n data.criticaltemp= true;\n }\nelse {\n msg.payload.temperatureEvent = \"No action\"\n }\n// Check if humidity is within the acceptable range\nif (humidity < minHumidity) {\n // Humidity is below the acceptable range\n data.humidityEvent = \"Below Min\";\n} else if (humidity > maxHumidity) {\n // Humidity is above the acceptable range\n data.humidityEvent = \"Above Max\";\n }\n \n\nelse {\n data.humidityEvent = \"No action\"\n }\n\n// Set turn AC variable based on conditions\nif (data.temperatureEvent === \"Above Max\" || data.humidityEvent === \"Above Max\" || data.criticaltemp==true) {\n data.turnAC = true; // Turn on AC\n} else {\n data.turnAC = false; // Turn off AC\n}\n\n\n\n// Return message\nreturn {payload: data};", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 340, + "y": 1260, + "wires": [ + [ + "d5a86c315783fbfe" + ] + ] + }, + { + "id": "d5a86c315783fbfe", + "type": "mqtt out", + "z": "a739aed4431ae770", + "name": "", + "topic": "sensordata", + "qos": "", + "retain": "", + "respTopic": "", + "contentType": "", + "userProps": "", + "correl": "", + "expiry": "", + "broker": "ff246c28cc0fa0af", + "x": 610, + "y": 1260, + "wires": [] + }, + { + "id": "4d49ddb3e8382883", + "type": "comment", + "z": "a739aed4431ae770", + "name": "bluetooth_interface", + "info": "", + "x": 90, + "y": 40, + "wires": [] + }, + { + "id": "18bf22ae7c0aa34a", + "type": "inject", + "z": "a739aed4431ae770", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 320, + "y": 900, + "wires": [ + [ + "db26524b32c2d7e8" + ] + ] } ] \ No newline at end of file -- GitLab