Node Red - Cisco Spark Integration: Code Review

#1

Hi,

As I am new and also not a programmer I want to ask you to do a review of my Cisco Spark integration. Basically my flow is working, but I think it can be done much better.

Goal: Contact BOT and request Temperature of several rooms. Only one user should be allowed to do this.

  1. Webhook: Receiving Notification, when Bot is contacted
  2. Parse for MessageID
  3. Request Message, based on MessageID
  4. Check for valid Username
  5. Check for command

I think this part is ok, I do not know it here something could be improved.
But now lets go ahead with the second part, and I am pretty sure, this is not a good implementation:

Upper Flow:
6) Check 4 different TemperatureSensors from Home-Assistant
7) Write the Temperature in a Global Variable
8) Set a Delay to get always the same order
9) Join all 4 Values into one message
10) Store the combined message to another global variable

Lower Flow:
11) Delay to have the temperature values ready when this part is executed
12) Get all neccessary information and prepare new message
13) Send message to Cisco Spark

[{"id":"11f54195.f9ffae","type":"Spark Webhook","z":"2068111c.8b052e","profileConfig":"fafb13de.28f9d","resource":"messages","event":"created","host":"https://SERVER","name":"","x":290,"y":360,"wires":[["9e94bac7.4fd588","eb1f760b.33c7e8"]]},{"id":"9e94bac7.4fd588","type":"debug","z":"2068111c.8b052e","name":"Webhook","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":500,"y":320,"wires":[]},{"id":"eb1f760b.33c7e8","type":"Spark Payload Parser","z":"2068111c.8b052e","name":"","parsers":[{"key":"id","as":"messageId"}],"x":510,"y":360,"wires":[["604b58aa.aa3f98","65619f55.e13d8"]]},{"id":"604b58aa.aa3f98","type":"debug","z":"2068111c.8b052e","name":"MessageID","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":670,"y":320,"wires":[]},{"id":"65619f55.e13d8","type":"Spark API","z":"2068111c.8b052e","profileConfig":"637e9d73.264534","apiUrl":"https://SERVER/api/cisco_spark_v1.json","resource":"messages","method":"getMessage","name":"","x":730,"y":360,"wires":[["823c70d2.d728f","a104b87e.2ecc28"]]},{"id":"823c70d2.d728f","type":"debug","z":"2068111c.8b052e","name":"messages","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":950,"y":320,"wires":[]},{"id":"d0c7c09f.f7a0a","type":"switch","z":"2068111c.8b052e","name":"match & route commands","property":"payload.text","propertyType":"msg","rules":[{"t":"eq","v":"/temp","vt":"str"},{"t":"eq","v":"Node-Red-BOT /temp","vt":"str"},{"t":"neq","v":"/temp","vt":"str"}],"checkall":"true","repair":false,"outputs":3,"x":1230,"y":360,"wires":[["b27548cc.a7fe38","b01cc36b.309f3","8caaef5e.726ec","14b92b4f.d22f65","bb2ba70c.6acd88","10f7cb25.c1b285"],["b27548cc.a7fe38","10f7cb25.c1b285"],["52002096.e17b4"]]},{"id":"b27548cc.a7fe38","type":"debug","z":"2068111c.8b052e","name":"OK","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1490,"y":320,"wires":[]},{"id":"52002096.e17b4","type":"debug","z":"2068111c.8b052e","name":"NOT OK","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1500,"y":400,"wires":[]},{"id":"b643af48.1ce16","type":"function","z":"2068111c.8b052e","name":"parse and format response","func":"// This function parses the Meraki Dashboard API response\n// and creates a message to POST to a Spark room.\n//response = msg.payload;\n//body = {}; //reset payload object for clarity\n//my_array = [];\n//counter = 0;\n//body.roomId = msg.roomId;\n\n//for (var key in response) {\n//  if (response.hasOwnProperty(key)) {\n//    counter += 1;\n//    var dev_mac = response[key].mac;\n//    var dev_serial = response[key].serial;\n//    var dev_model = response[key].model;\n//    my_array.push('`'+counter+\". model: \"+dev_model+\", serial: \"+dev_serial+ \", mac:\"+dev_mac+'`\\n');\n//  }\n//}\n//\n//var msg_markdown = my_array.join(\"\\n\");\n//body.markdown = msg_markdown;\n//msg.payload = {};\n//msg.payload.body = body;\n//return msg;\n//body = {};\n//body.roomId = msg.roomId;\n\n// ******************\n// Set Your Variables\n// ******************\nvar accessToken = \"TOKEN\"; // Your Access Token\nvar roomId = msg.payload.roomId;\nvar Temperatur = global.get(\"Temperatur-Webex\");\n\n// -- -- -- -- -- --\n// Build API Call\nmsg.url = \"https://api.ciscospark.com/v1/messages\";\nmsg.headers = { \n    'content-type': 'application/json',\n    'authorization': 'Bearer '+ accessToken \n};\nmsg.payload ={ \n    roomId: roomId,\n    markdown: Temperatur\n}\nmsg.method = \"post\";\n\nreturn msg;","outputs":1,"noerr":0,"x":1700,"y":360,"wires":[["92a89c8b.4cab6","52e70916.505608"]]},{"id":"92a89c8b.4cab6","type":"http request","z":"2068111c.8b052e","name":"","method":"use","ret":"txt","url":"","tls":"","x":1910,"y":360,"wires":[[]]},{"id":"52e70916.505608","type":"debug","z":"2068111c.8b052e","name":"Response","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1900,"y":320,"wires":[]},{"id":"a104b87e.2ecc28","type":"switch","z":"2068111c.8b052e","name":"match & route commands","property":"payload.personEmail","propertyType":"msg","rules":[{"t":"eq","v":"EMAIL","vt":"str"},{"t":"neq","v":"EMAIL","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":990,"y":360,"wires":[["d0c7c09f.f7a0a"],["ef2af161.ebac3"]]},{"id":"ef2af161.ebac3","type":"debug","z":"2068111c.8b052e","name":"Denied","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1180,"y":400,"wires":[]},{"id":"bb2ba70c.6acd88","type":"api-current-state","z":"2068111c.8b052e","name":"Kinderzimmer","server":"e76cb70.9b3bd48","halt_if":"","override_topic":true,"override_payload":true,"entity_id":"sensor.kinderzimmer_dominik_motion_sensor_temperature","x":1520,"y":120,"wires":[["725dc097.79c13"]]},{"id":"14b92b4f.d22f65","type":"api-current-state","z":"2068111c.8b052e","name":"Vorraum","server":"e76cb70.9b3bd48","halt_if":"","override_topic":true,"override_payload":true,"entity_id":"sensor.vorraum_dach_motion_sensor_temperature","x":1500,"y":160,"wires":[["7a2039a6.99a3e8"]]},{"id":"8caaef5e.726ec","type":"api-current-state","z":"2068111c.8b052e","name":"Arbeitszimmer","server":"e76cb70.9b3bd48","halt_if":"","override_topic":true,"override_payload":true,"entity_id":"sensor.arbeitszimmer_dach_motion_sensor_temperature","x":1520,"y":200,"wires":[["93a61f3b.04752"]]},{"id":"b01cc36b.309f3","type":"api-current-state","z":"2068111c.8b052e","name":"Außentemperatur","server":"e76cb70.9b3bd48","halt_if":"","override_topic":true,"override_payload":true,"entity_id":"sensor.pws_temp_c","x":1530,"y":240,"wires":[["e772e786.941c78"]]},{"id":"e772e786.941c78","type":"function","z":"2068111c.8b052e","name":"","func":"msg.payload = \"\\n\" + \"Außentemperatur: \" + msg.payload + \" °C\" + \"\\n\";\nreturn msg;","outputs":1,"noerr":0,"x":1690,"y":240,"wires":[["83565c04.3d48"]]},{"id":"93a61f3b.04752","type":"function","z":"2068111c.8b052e","name":"","func":"msg.payload = \"Arbeitszimmer: \" + msg.payload + \" °C\" + \"\\n\";\nreturn msg;","outputs":1,"noerr":0,"x":1690,"y":200,"wires":[["2ddde80d.6cb868"]]},{"id":"7a2039a6.99a3e8","type":"function","z":"2068111c.8b052e","name":"","func":"msg.payload = \"Vorraum: \" + msg.payload + \" °C\" + \"\\n\";\nreturn msg;","outputs":1,"noerr":0,"x":1690,"y":160,"wires":[["ad7daad0.7ad728"]]},{"id":"725dc097.79c13","type":"function","z":"2068111c.8b052e","name":"","func":"msg.payload = \"Kinderzimmer: \" + msg.payload + \" °C\";\nreturn msg;","outputs":1,"noerr":0,"x":1690,"y":120,"wires":[["79e16106.d65dd"]]},{"id":"79e16106.d65dd","type":"delay","z":"2068111c.8b052e","name":"","pauseType":"delay","timeout":"15","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1830,"y":120,"wires":[["83565c04.3d48"]]},{"id":"ad7daad0.7ad728","type":"delay","z":"2068111c.8b052e","name":"","pauseType":"delay","timeout":"10","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1830,"y":160,"wires":[["83565c04.3d48"]]},{"id":"2ddde80d.6cb868","type":"delay","z":"2068111c.8b052e","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1830,"y":200,"wires":[["83565c04.3d48"]]},{"id":"83565c04.3d48","type":"join","z":"2068111c.8b052e","name":"","mode":"custom","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"4","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"","reduceFixup":"","x":2010,"y":180,"wires":[["68b1a53f.71007c","f178381.358b2c8"]]},{"id":"68b1a53f.71007c","type":"debug","z":"2068111c.8b052e","name":"Temperaturen","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":2180,"y":140,"wires":[]},{"id":"f178381.358b2c8","type":"function","z":"2068111c.8b052e","name":"Set Variable Temperaturen","func":"global.set(\"Temperatur-Webex\",msg.payload);","outputs":1,"noerr":0,"x":2220,"y":180,"wires":[[]]},{"id":"10f7cb25.c1b285","type":"delay","z":"2068111c.8b052e","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":1500,"y":360,"wires":[["b643af48.1ce16"]]},{"id":"fafb13de.28f9d","type":"Spark Authentication","z":0,"name":"ebnerjoh_nr_bot"},{"id":"637e9d73.264534","type":"Spark Authentication","z":0,"name":"Webex Team Webhook"},{"id":"e76cb70.9b3bd48","type":"server","z":"","name":"Home Assistant","url":"https://SERVER","pass":"PASSWORD"}]

Best Regards,
Johannes

0 Likes

#2

If you have to fudge in some delays so that your messages arrive in some expected order, then there is certainly room for improvement…

Since nodejs is single-threaded, I doubt there is any advantage to splitting your flow and trying to join the parts in a particular order. It would be simpler to wire all 4 HA calls in series, with a change node in between them to move the previous payload to some other property.

0 Likes