Here are the nodes without the function node output connections. Clicking "Simcoe" works fine.
When the inject of 'Watford' is clicked, the get http node
should just flash requesting
and then clear the node status, as occurs with "Simcoe" ... and it does but only when just a debug is connected to the get http
output (not the function node). There is never any lock up in this case.
When the function node is connected to the http output and Watford clicked, the node.status of the get http
node stays stuck on requesting
and then the "Loading Node Credentials" eventually pops up and NR is locked up. Incidentally the 'port' that seems to be locked out (as I recall) is local host:1880.
Here are the nodes and code:
[{"id":"a6278fd5ae65c9e3","type":"function","z":"33029ff0c3176c55","name":"Weather Forfecast {WF}","func":"\n// Code compatible with: https://weather.gc.ca/rss/city/on-161_e.xml\n\n// -------------------------------------- function getNumber() ------------------------------------------- \nfunction getNumber(string) { // extracts numbers from a string\n // Using match with regEx\n let matches = string.match(/\\d+/g);\n if (matches && typeof(matches[1]) === 'undefined') return(matches[0])\n else if (matches) return(matches[0] +'.'+ matches[1])\n else return(string) ; }\n\n// Set variable for process monitor.\ncontext.global.activity_tab = \"Weather: \";\ncontext.global.activity_node = \"Get latest forecast\";\ncontext.global.activity = context.global.activity_tab + context.global.activity_node;\n\n// ======================================= CONFIRM GOOD DATA ==============================================\nif (msg.payload.indexOf(\"ENOTFOUND\") > -1 || msg.payload.indexOf(\"Error 404\") > -1) {\n node.warn(\"{WF 19} HTTP Error: Failed to get weather alert info at https://weather.gc.ca/rss/city/on-161_e.xml\" );\n return; }\nif (msg.payload.indexOf( \"- Weather - Environment Canada</title>\" ) === -1) {\n node.status({fill: 'grey', shape: 'ring', text: 'Web fail, using previous info' });\n node.warn('{WF 23} Weather data retrieve failure from XML site.');\n var forecast = context.previous_data;\n} else {\n forecast = msg.payload;\n context.previous_data = forecast;\n}\nif (msg.payload === 'undefined') { node.warn(\"{WF 29} ERROR: No weather data to use\"); return; }\n\nvar logTime = context.global.ampm_timestamp();\nvar x = 0, tag1 = 0, tag2 = 0, direction, word = 0, string, logMsg = null; \nvar now = new Date();\n\n// ------------------------------------------- GET LOCATION INFO -----------------------------------------\nvar tag = '<title>';\ntag1 = msg.payload.indexOf(tag) + tag.length;\ntag2 = msg.payload.indexOf(' - Weather - Environment Canada');\n tag = msg.payload.substring(tag1, tag2); // IE: 'Simcoe - Delhi - Norfolk' or 'Annapolis County'\nif (tag.indexOf(\" - \") > -1) var location = tag.substring(0, tag.indexOf(\" - \"))\nelse location = tag; // IE: 'Simcoe' or 'Annapolis County'\n//node.warn('{WF 42} ' + location);\n\n// ======================================= WARNINGS & WATCHES CHECK =======================================\ntag1 = forecast.indexOf('term=\"Warnings and Watches\"/>') + 53;\ntag2 = forecast.indexOf('</summary>', tag1);\nvar warning = forecast.substring(tag1, tag2);\nif (warning != \"No watches or warnings in effect.\") {\n node.warn(\"{WF 49} \" + warning);\n// logMsg = {payload: logTime + \"{WF 50} \" + warning}; \n}\nif (warning.length > 30 ) warning = \"Weather warning. \";\nnode.status({fill: 'grey', shape: 'ring', text: location + \": Weather data read\" });\n\n// ======================================= EXTRACT RELEVANT TECHNICAL DATA ================================\nconst techheaders = [\"<b>Temperature:</b>\", \"<b>Pressure / Tendency:</b>\", \"<b>Humidity:</b>\", \"<b>Wind:</b>\", \n \"<b>Air Quality Health Index:</b>\"]; \nconst winds = [\" N \", 'north', \" E \", 'east', \" W \", 'west', \" S \", 'south',\n \" NE \", 'northeast', \" NW \", 'northwest', \" SE \", 'southeast', \" SW \", 'southwest',\n \" WSW \", 'west, southwest', \" ESE \", 'east, southeast', \" WNW \", 'west, northwest', \" ENE \", 'east, northeast',\n \" SSW \", 'south, southwest', \" NNW \", 'north, northwest', \" SSE \", 'south, southeast', \" NNE \", 'north, northeast']\nvar techdata = [];\n\n// Extract strings based on techheaders IE: <b>Temperature:</b> 4.3°C\nwhile (x < techheaders.length) {\n if (forecast.indexOf(techheaders[x]) > -1) {\n tag1 = forecast.indexOf(techheaders[x]);\n tag2 = forecast.indexOf('<br/>', tag1);\n techdata[x] = forecast.substring(tag1, tag2);\n ++x; } }\n\n// Is it below zero degrees out?\nif (techdata[0].indexOf(\"-\") > -1) var minus = 'minus '\nelse minus = '';\n\n// Fix wording IE: make 'NNW' into 'north, northwest' and also extract number value from string\nvar value = [], direction; x = 0;\nwhile (x < techdata.length) {\n word = 0;\n if (techdata[x].indexOf(\" calm km/h\") > -1) techdata[x] = \" calm \";\n while (word < winds.length) { if (techdata[x].indexOf(winds[word]) > -1) direction = winds[word + 1]; word = word + 2; }\n value[x] = getNumber(techdata[x]); // extract number from string using function above (regEx)\n ++x; }\n \n// ======================================= EXTRACT RELEVANT DAILY DATA ===================================== \nconst period = [\"Sunday:\", \"Sunday night:\", \"Monday:\", \"Monday night:\", \"Tuesday:\", \"Tuesday night:\", \n \"Wednesday:\", \"Wednesday night:\", \"Thursday:\", \"Thursday night:\", \n \"Friday:\", \"Friday night:\", \"Saturday:\", \"Saturday night:\" ];\nvar start = [0, 2, 4, 6, 8, 10, 12 ];\nvar report = [];\n\nx = 0, tag1 = 0, tag2 = 0; \nvar dow = now.getDay(), // Sun:0, Mon:1 .... Sat:6\n day = start[dow], // need to start the report[x] array at today, not Sunday, so days are in proper order\n today = start[dow]; // 'day' gets incremented, need this to do 'today' and 'tomorrow' replacements\n\nwhile ( x < 13 ) {\n if (forecast.indexOf(period[day]) > -1) { \n tag1 = forecast.indexOf(period[day]);\n tag2 = forecast.indexOf('</title>', tag1) }\n report[x] = forecast.substring(tag1, tag2);\n if (report[x].indexOf(period[today]) > -1) report[x] = report[x].replace(period[today], \"Today.\");\n if (report[x].indexOf(period[today+1]) > -1) report[x] = report[x].replace(period[today+1], \"Tonight.\");\n if (report[x].indexOf(period[today+2]) > -1) report[x] = report[x].replace(period[today+2], \"Tomorrow.\");\n if (report[x].indexOf(period[today+3]) > -1) report[x] = report[x].replace(period[today+3], \"Tomorrow night.\"); \n while (report[x].indexOf(\":\") > -1) { report[x] = report[x].replace(\":\", \", \"); } \n ++day;\n if (day === 14) day = 0; // go now to 'Sunday:' \n //node.warn(report[x]);\n ++x; } \n\n// ---------------------------------------------- CLEAN UP UNUSABLE TEXT -------------------------------------\nconst fixes = [\"POP\", 'Possibility of precipitation,'];\n\nx = 0;\nwhile (x < report.length) { \n word = 0;\n while (report[x].indexOf(fixes[word]) > -1 ) { report[x] = report[x].replace(fixes[word], fixes[word + 1]); word = word + 2;}\n if (report[x].charAt(report[x].length - 1) === '%') report[x] = report[x] + '. ';\n ++x; }\n\n// ---------------------------------------------- BUILD THE FORECASTS --------------------------------------\nvar greeting = 'Good morning everyone. ';\nif (now.getHours() >= 12 && now.getHours() < 18) greeting = 'Good afternoon folks. ';\nif (now.getHours() >= 18 && now.getHours() < 23) greeting = 'Good evening all. ';\n\n// this next bit is just for the forecast given at the exact time a user has set\nvar meridiem = now.getHours() >= 12 ? \" P M\" : \" A M\";\nvar hour = now.getHours() > 12 ? now.getHours() - 12 : now.getHours();\nif ( context.flow.trigger === \"timed_forecast\") greeting = greeting + 'Here is your ' + hour + meridiem \nelse greeting = greeting + 'Here is the latest ' + location;\n\n// Build the temperature report\nif (value[3] === ' calm ') var temp_string = \"The current temperature in \" + global.get(\"home_town\") + \" is \" + minus + Math.round(value[0]) + \" degrees. \" +\n \"The humidity is \" + value[2] + \" percent. Currently winds are calm \";\nelse temp_string = \"The current temperature in \" + global.get(\"home_town\") + \" is \" + minus + Math.round(value[0]) + \" degrees. \" +\n \"The humidity is \" + value[2] + \" percent. and currently \" +\n \"winds are from the \" + direction + \" at \" + value[3] + \" kilometers per hour \";\n\n// Creative multiple report endings\nvar end1 = \" And that's the current weather story\"; \nvar end2 = \" And that's how it's looking\";\nvar end3 = \" \";\n\n// Build the short range forecast\nvar forecast1 = greeting + \" short range weather forecast. \" + report[0] + \" \" + report[1] + \" \" + report[2] + \" \" + report[3] +\n \" And that's how it looks\";\n\n// Build the long range forcast\nx = 0;\nvar forecast2 = greeting + ' long range weather forecast. ';\nwhile (x < report.length) {\n forecast2 = forecast2 + \" \" + report[x];\n if (x > 3) x = x + 2\n else ++x; }\n\n\nforecast2 = forecast2 + \" And that's the whole weather story\";\n\n// ============================================= SET UP SPEECH MESSAGE ======================================\nvar voiceMsg = { speak: \"\", amptime: 10, voice: 'Callie', applause: false, bing: true, node: \"Weather {WX}\" };\n\nif (flow.get(\"r_type\") === 'short') var output = forecast1\nelse output = forecast2; \n\nif ( context.flow.trigger === \"Temperature\" ) voiceMsg.speak = temp_string; // set in 'Selector' node\nif ( context.flow.trigger === \"Forecast\" ) voiceMsg.speak = output;\nif ( context.flow.trigger === \"timed_forecast\") voiceMsg.speak = output;\nif ( context.flow.trigger === \"motion_mainfloor\") voiceMsg.speak = output;\n\n// The following RegEx will 1. clear carriage return => space 2. replace multiple spaces by a single one\n// 3. to clear leading and trailing spaces (same as jQuery trim())\nvoiceMsg.speak = voiceMsg.speak.replace(/[\\n\\r]+/g, ' ').replace(/\\s{2,}/g,' ').replace(/^\\s+|\\s+$/,'') ;\nvar toast = {payload: voiceMsg.speak };\nlogMsg = {payload: logTime + '{WF 165} ' + voiceMsg.speak + \"\\n\\n\"};\nreturn [toast, voiceMsg, logMsg ];\n\n/*\n// Fix words that \"swift\" synthesizer sometimes seems to stumble with.\nwhile (content.indexOf(\"high minus\") > -1) {content = content.replace(\"high minus\", \"high of minus\")}\nwhile (content.indexOf(\"High minus\") > -1) {content = content.replace(\"High minus\", \"High of minus\")}\n*/","outputs":3,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":640,"y":250,"wires":[[],["efaed0c32255a661"],[]],"outputLabels":["Toast","voiceMsg","logMsg"]},{"id":"cd8ee1cb630163a7","type":"http request","z":"33029ff0c3176c55","name":"Get http XML","method":"GET","ret":"txt","paytoqs":"ignore","url":"{{{link}}}","tls":"","persist":false,"proxy":"","insecureHTTPParser":false,"authType":"","senderr":false,"headers":[],"x":430,"y":250,"wires":[["a6278fd5ae65c9e3","fb3d203aca16abc8"]],"info":"Simcoe\r\nhttps://weather.gc.ca/rss/city/on-161_e.xml\r\n\r\nLambton Shores\r\nhttps://weather.gc.ca/rss/city/on-46_e.xml\r\n\r\nPEI\r\nhttps://weather.gc.ca/rss/city/on-27_e.xml\r\n"},{"id":"efaed0c32255a661","type":"debug","z":"33029ff0c3176c55","name":"debug 59","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"speak","targetType":"msg","statusVal":"","statusType":"auto","x":835,"y":270,"wires":[],"l":false},{"id":"345c7ad32ca85bc4","type":"link out","z":"33029ff0c3176c55","name":"Voice to Amp","mode":"link","links":["4ca5302f500ae9c6"],"x":885,"y":230,"wires":[],"l":true},{"id":"251e5416ad975786","type":"ui_toast","z":"33029ff0c3176c55","position":"top right","displayTime":"15","highlight":"red","sendall":true,"outputs":0,"ok":"OK","cancel":"","raw":true,"className":"","topic":"Weather Message:","name":"Weather Toast","x":895,"y":190,"wires":[]},{"id":"d91975108ecfd5b3","type":"comment","z":"33029ff0c3176c55","name":"This is the short / long range weather forecast process","info":"","x":515,"y":195,"wires":[]},{"id":"2e4ba7f42c4f29c2","type":"inject","z":"33029ff0c3176c55","name":"Simcoe","props":[{"p":"link","v":"https://weather.gc.ca/rss/city/on-161_e.xml","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":140,"y":250,"wires":[["eb2d9707390dbe78"]]},{"id":"eb2d9707390dbe78","type":"function","z":"33029ff0c3176c55","name":"Set call type","func":"context.flow.trigger = \"Forecast\";\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":285,"y":250,"wires":[["cd8ee1cb630163a7"]]},{"id":"b345454ef6502bc5","type":"inject","z":"33029ff0c3176c55","name":"Watford","props":[{"p":"link","v":"https://weather.gc.ca/rss/city/on-46_e.xml","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":135,"y":300,"wires":[["eb2d9707390dbe78"]]},{"id":"fb3d203aca16abc8","type":"debug","z":"33029ff0c3176c55","name":"http data","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":595,"y":315,"wires":[]}]