Updating Mustache values with Web Sockets

220 views
Skip to first unread message

Adam S

unread,
May 15, 2015, 10:17:02 AM5/15/15
to node...@googlegroups.com
So I was reading Peters blog about creating and using web sockets.  I got everything working as he described fine, and it make sense, but when I started making modifications that's when I'm running in to trouble.  I have a flow (see below) that will take a global variable and display it when the page loads - works fine - but when I try to update that global variable through the web socket it doesn't actually update.  I'm further confused by the fact that I made a completely new variable to update the page only when the update button is clicked and it still doesn't change the value.  I would expect to see some sort of error, or a 0, or anything different at all.  I'm completely confident that I'm doing something wrong here but I have no idea what.  My only guess is that maybe the values for mustache template only load once, and since clicking the button does not refresh the page it does not update the values.  Should I be passing variable in a different way?  I made the flow so that anyone should be able to copy and paste it and see the results I do (my values actually come from a temp sensor and a completely different flow).

[{"id":"8d3eeda3.29971","type":"websocket-listener","path":"/app","wholemsg":"false"},{"id":"6a9ee410.97203c","type":"websocket in","name":"app in","server":"8d3eeda3.29971","client":"","x":75.88333129882812,"y":191.88333129882812,"z":"7f6f92e8.afd0c4","wires":[["f2a65219.75459"]]},{"id":"f2a65219.75459","type":"function","name":"Kill Session","func":"msg._session=\"\";\n\nmsg.current = {\n    insidetempupdate: context.global.insidetemp\n};\n\nreturn msg; ","outputs":1,"valid":true,"x":246.88333129882812,"y":191.88330078125,"z":"7f6f92e8.afd0c4","wires":[["37b7c1c9.19b646","40a8165b.105b7"]]},{"id":"37b7c1c9.19b646","type":"websocket out","name":"app out","server":"8d3eeda3.29971","client":"","x":418.8833312988281,"y":191.88333129882812,"z":"7f6f92e8.afd0c4","wires":[]},{"id":"c72b4520.37d978","type":"http in","name":"test page in","url":"/test","method":"get","x":85.88333129882812,"y":283.8833312988281,"z":"7f6f92e8.afd0c4","wires":[["380d11b2.79b906"]]},{"id":"5b74dd07.870b2c","type":"http response","name":"test page out","x":669.88330078125,"y":282.88330078125,"z":"7f6f92e8.afd0c4","wires":[]},{"id":"3a290a4c.4d20ae","type":"template","name":"","field":"payload","format":"handlebars","template":"<html>\n<head>\n\t<title>Simple Display</title>\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t<link rel=\"stylesheet\" href=\"https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css\">\n\t<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js\"></script>\n\t<script src=\"https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js\"></script>\n</head>\n\n<script type=\"text/javascript\">\n\tvar server = window.location.hostname;\n\tvar topics = {};\n\tvar wsUriC = \"ws://\"+server+\":1880/app\";\n\tvar ws;\n\tfunction wsConnectC() {\n\t\tconsole.log(\"connect\",wsUriC);\n\t\tws = new WebSocket(wsUriC);\n\t\t$(\"#part2\").html({{current.insidetemp}});\n\t\tws.onmessage = function(msg) {\n\t\t\tvar line = \"\";\n\t\t\tvar intemp = {{current.insidetemp}} + 100;\n\t\t\tconsole.log(msg.data);\n\t\t\tvar fromPage=JSON.parse(msg.data);\n\t\t\tif (fromPage.part1!=\"\") $(\"#part1\").html(fromPage.part1); else $(\"#part1\").html(\"!Empty!\");\n\t\t\t$(\"#part2\").html({{current.insidetempupdate}});\n\t\t\t//document.getElementById('element').innerHTML = {{current.insidetemp}};\n\t\t}\n\t\tws.onopen = function() {\n\t\t\t$(\"#status\").html(\"connected\");\n\t\t\tconsole.log(\"connected\");\n\t\t}\n\t\tws.onclose = function() {\n\t\t\t$(\"#status\").html(\"not connected\");\n\t\t\tsetTimeout(wsConnectC,1000);\n\t\t}\n\t}\n   \n\tfunction sendMessage(){\n\t\t// send message back to page in simple JSON format\n\t\t// example {\"part1\":\"Hello\",\"part2\":\"50\"}\n\t\tvar toPage='{\"part1\":\"'+$(\"#txtMsg_1\").val()+'\",\"part2\":\"'+$(\"#slider_1\").val()+'\",\"part3\":\"3\"}';\n\t\tws.send(toPage);\n\t} // end sendMessage\n\n</script>\n<body onload=\"wsConnectC();\" onunload=\"ws.disconnect;\">\n\t<div data-role=\"page\" id=\"one\">\n\t\t<div data-role=\"header\">\n\t\t\t<h1>Websockets Test Page</h1>\n\t\t</div>\n\t\t<div role=\"main\" class=\"ui-content\">\n\t\t\t<h1>Temperature Display</h1>\n\t\t\t<div id=\"status\">status unknown</div>   \n\t\t\t<input id=\"txtMsg_1\" />           \n\t\t\t<div id=\"part1\">!Empty!</div>\n\t\t\t<hr/>\n\t\t\t<div id=\"part2\">0</div>\n\t\t\t<hr/>\n\t\t\t<label for=\"slider_1\">Input slider:</label>\n\t\t\t<input type=\"range\" id=\"slider_1\" value=\"60\" min=\"0\" max=\"100\"  />\n\t\t\t<input type=\"button\" value=\"Update\" onClick=\"sendMessage()\" />\n\t\t</div>\n\t</div>\n</body>\n</html>","x":482.3833312988281,"y":282.88330078125,"z":"7f6f92e8.afd0c4","wires":[["5b74dd07.870b2c"]]},{"id":"380d11b2.79b906","type":"function","name":"Get Current Values","func":"context.global.insidetemp = 80\n\nmsg.current = {\n    insidetemp: context.global.insidetemp,\n    outsidetemp: context.global.outsidetemp,\n    fansdisabled: context.global.fansdisabled\n};\nreturn msg;","outputs":1,"valid":true,"x":266.8833312988281,"y":283.88330078125,"z":"7f6f92e8.afd0c4","wires":[["3a290a4c.4d20ae","6de9a252.d6d404"]]},{"id":"6de9a252.d6d404","type":"debug","name":"","active":false,"console":"false","complete":"current.insidetemp","x":603.8833312988281,"y":215.88333129882812,"z":"7f6f92e8.afd0c4","wires":[]},{"id":"40a8165b.105b7","type":"debug","name":"","active":true,"console":"false","complete":"true","x":478.8833312988281,"y":124.88330078125,"z":"7f6f92e8.afd0c4","wires":[]},{"id":"3d1e8870.f96918","type":"inject","name":"","topic":"","payload":"90","payloadType":"string","repeat":"","crontab":"","once":false,"x":78.88333129882812,"y":90.88333129882812,"z":"7f6f92e8.afd0c4","wires":[["a1dc86a1.021228"]]},{"id":"a1dc86a1.021228","type":"function","name":"","func":"context.global.insidetemp = msg.payload\nreturn msg;","outputs":1,"valid":true,"x":203.88333129882812,"y":92.88333129882812,"z":"7f6f92e8.afd0c4","wires":[["f2a65219.75459"]]}]

Nicholas O'Leary

unread,
May 15, 2015, 6:23:17 PM5/15/15
to Node-RED Mailing LIst
Hi Adam,

I'm not entirely clear what interactions you're trying to achieve, but here are some things I can see in your flow.

- the first line of "Get Current Values" sets context.global.insidetemp to 80 every time you refresh the page - regardless of what it may have been set to in another flow.
- if you delete that first list, then after clicking the Inject node (which causes it to be set to 90), when you refresh the page the value is now shown as 90

When the browser requests /flow, the mustache template is evaluated with the current value at that point in time and the result is sent to the browser. Once it is in the browser, its up to you to handle the updates you want. All of the mustache tags in the onmessage function will have been replaced.

The message that arrives over the websocket when you hit the inject button is currently just the value "90" - that isn't very helpful in being able to distinguish what the value is. In "Kill Session", you set msg.current to an object containing the new value, but the websocket node sends msg.payload. So if you change (in "Kill Session") msg.change to msg.payload, then the onmessage function in your page can be something like:
        
ws.onmessage = function(msg) {
var fromPage=JSON.parse(msg.data);
        if (fromPage.insidetempupdate) {
$("#part2").html(fromPage.insidetempupdate);
        }
if (fromPage.part1!="") $("#part1").html(fromPage.part1); else $("#part1").html("!Empty!");
}




Nick

On 15 May 2015 at 15:17, Adam S <ats1...@gmail.com> wrote:
So I was reading Peters blog about creating and using web sockets.  I got everything working as he described fine, and it make sense, but when I started making modifications that's when I'm running in to trouble.  I have a flow (see below) that will take a global variable and display it when the page loads - works fine - but when I try to update that global variable through the web socket it doesn't actually update.  I'm further confused by the fact that I made a completely new variable to update the page only when the update button is clicked and it still doesn't change the value.  I would expect to see some sort of error, or a 0, or anything different at all.  I'm completely confident that I'm doing something wrong here but I have no idea what.  My only guess is that maybe the values for mustache template only load once, and since clicking the button does not refresh the page it does not update the values.  Should I be passing variable in a different way?  I made the flow so that anyone should be able to copy and paste it and see the results I do (my values actually come from a temp sensor and a completely different flow).

[{"id":"8d3eeda3.29971","type":"websocket-listener","path":"/app","wholemsg":"false"},{"id":"6a9ee410.97203c","type":"websocket in","name":"app in","server":"8d3eeda3.29971","client":"","x":75.88333129882812,"y":191.88333129882812,"z":"7f6f92e8.afd0c4","wires":[["f2a65219.75459"]]},{"id":"f2a65219.75459","type":"function","name":"Kill Session","func":"msg._session=\"\";\n\nmsg.current = {\n    insidetempupdate: context.global.insidetemp\n};\n\nreturn msg; ","outputs":1,"valid":true,"x":246.88333129882812,"y":191.88330078125,"z":"7f6f92e8.afd0c4","wires":[["37b7c1c9.19b646","40a8165b.105b7"]]},{"id":"37b7c1c9.19b646","type":"websocket out","name":"app out","server":"8d3eeda3.29971","client":"","x":418.8833312988281,"y":191.88333129882812,"z":"7f6f92e8.afd0c4","wires":[]},{"id":"c72b4520.37d978","type":"http in","name":"test page in","url":"/test","method":"get","x":85.88333129882812,"y":283.8833312988281,"z":"7f6f92e8.afd0c4","wires":[["380d11b2.79b906"]]},{"id":"5b74dd07.870b2c","type":"http response","name":"test page out","x":669.88330078125,"y":282.88330078125,"z":"7f6f92e8.afd0c4","wires":[]},{"id":"3a290a4c.4d20ae","type":"template","name":"","field":"payload","format":"handlebars","template":"<html>\n<head>\n\t<title>Simple Display</title>\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t<link rel=\"stylesheet\" href=\"https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css\">\n\t<script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js\"></script>\n\t<script src=\"https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js\"></script>\n</head>\n\n<script type=\"text/javascript\">\n\tvar server = window.location.hostname;\n\tvar topics = {};\n\tvar wsUriC = \"ws://\"+server+\":1880/app\";\n\tvar ws;\n\tfunction wsConnectC() {\n\t\tconsole.log(\"connect\",wsUriC);\n\t\tws = new WebSocket(wsUriC);\n\t\t$(\"#part2\").html({{current.insidetemp}});\n\t\tws.onmessage = function(msg) {\n\t\t\tvar line = \"\";\n\t\t\tvar intemp = {{current.insidetemp}} + 100;\n\t\t\tconsole.log(msg.data);\n\t\t\tvar fromPage=JSON.parse(msg.data);\n\t\t\tif (fromPage.part1!=\"\") $(\"#part1\").html(fromPage.part1); else $(\"#part1\").html(\"!Empty!\");\n\t\t\t$(\"#part2\").html({{current.insidetempupdate}});\n\t\t\t//document.getElementById('element').innerHTML = {{current.insidetemp}};\n\t\t}\n\t\tws.onopen = function() {\n\t\t\t$(\"#status\").html(\"connected\");\n\t\t\tconsole.log(\"connected\");\n\t\t}\n\t\tws.onclose = function() {\n\t\t\t$(\"#status\").html(\"not connected\");\n\t\t\tsetTimeout(wsConnectC,1000);\n\t\t}\n\t}\n   \n\tfunction sendMessage(){\n\t\t// send message back to page in simple JSON format\n\t\t// example {\"part1\":\"Hello\",\"part2\":\"50\"}\n\t\tvar toPage='{\"part1\":\"'+$(\"#txtMsg_1\").val()+'\",\"part2\":\"'+$(\"#slider_1\").val()+'\",\"part3\":\"3\"}';\n\t\tws.send(toPage);\n\t} // end sendMessage\n\n</script>\n<body onload=\"wsConnectC();\" onunload=\"ws.disconnect;\">\n\t<div data-role=\"page\" id=\"one\">\n\t\t<div data-role=\"header\">\n\t\t\t<h1>Websockets Test Page</h1>\n\t\t</div>\n\t\t<div role=\"main\" class=\"ui-content\">\n\t\t\t<h1>Temperature Display</h1>\n\t\t\t<div id=\"status\">status unknown</div>   \n\t\t\t<input id=\"txtMsg_1\" />           \n\t\t\t<div id=\"part1\">!Empty!</div>\n\t\t\t<hr/>\n\t\t\t<div id=\"part2\">0</div>\n\t\t\t<hr/>\n\t\t\t<label for=\"slider_1\">Input slider:</label>\n\t\t\t<input type=\"range\" id=\"slider_1\" value=\"60\" min=\"0\" max=\"100\"  />\n\t\t\t<input type=\"button\" value=\"Update\" onClick=\"sendMessage()\" />\n\t\t</div>\n\t</div>\n</body>\n</html>","x":482.3833312988281,"y":282.88330078125,"z":"7f6f92e8.afd0c4","wires":[["5b74dd07.870b2c"]]},{"id":"380d11b2.79b906","type":"function","name":"Get Current Values","func":"context.global.insidetemp = 80\n\nmsg.current = {\n    insidetemp: context.global.insidetemp,\n    outsidetemp: context.global.outsidetemp,\n    fansdisabled: context.global.fansdisabled\n};\nreturn msg;","outputs":1,"valid":true,"x":266.8833312988281,"y":283.88330078125,"z":"7f6f92e8.afd0c4","wires":[["3a290a4c.4d20ae","6de9a252.d6d404"]]},{"id":"6de9a252.d6d404","type":"debug","name":"","active":false,"console":"false","complete":"current.insidetemp","x":603.8833312988281,"y":215.88333129882812,"z":"7f6f92e8.afd0c4","wires":[]},{"id":"40a8165b.105b7","type":"debug","name":"","active":true,"console":"false","complete":"true","x":478.8833312988281,"y":124.88330078125,"z":"7f6f92e8.afd0c4","wires":[]},{"id":"3d1e8870.f96918","type":"inject","name":"","topic":"","payload":"90","payloadType":"string","repeat":"","crontab":"","once":false,"x":78.88333129882812,"y":90.88333129882812,"z":"7f6f92e8.afd0c4","wires":[["a1dc86a1.021228"]]},{"id":"a1dc86a1.021228","type":"function","name":"","func":"context.global.insidetemp = msg.payload\nreturn msg;","outputs":1,"valid":true,"x":203.88333129882812,"y":92.88333129882812,"z":"7f6f92e8.afd0c4","wires":[["f2a65219.75459"]]}]

--
http://nodered.org
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Message has been deleted

Dave C-J

unread,
May 18, 2015, 11:08:09 AM5/18/15
to node...@googlegroups.com
Adam

when you configure the websocket endpoint you can select Send/Receive entire message....
Inline images 1

Adam S

unread,
May 18, 2015, 11:57:47 AM5/18/15
to node...@googlegroups.com
Yep, that's why I deleted the message shortly after I posted it.

Anyway, I'm stuck trying to pass more than one variable to the websocket now - this would be the sendMessage() function.  I tried to send the variables with JSON but when it gets to the websocket its value is [object Object] and if I pass a string containing the JSON it's just a string, I can't extract the values in a function node.  What do I need to do to pass more than 1 variable?

Dave C-J

unread,
May 18, 2015, 12:19:44 PM5/18/15
to node...@googlegroups.com
So where are you seeing Object object ? Is this inbound to Node-RED now - or in the browser dev console ?
Typically that is what you get when trying to console.log an object... so at that point it is probably the object you want...

Normally at the browser end you would have something like

ws.onmessage = function (evt) {
        console.log(evt); /// wil probably report [Object object]
        try {
            var data = JSON.parse(evt.data); // try to parse out the data from the data part of the object
        } catch (e) {
            console.log("BAD PARSE",evt.data);  //  just dump out the data part if not...
            return;
        }
    }

Adam S

unread,
May 18, 2015, 1:08:57 PM5/18/15
to node...@googlegroups.com
I'm actually trying to send variables from my webpage back to the websocket then through a function node to set global variables.  I'm seeing [object Object] in the debug node output right after the websocket in node.  I had an idea and was testing parsing the string back in to JSON in the function node after the websocket in node, but I was getting a Uncaught SyntaxError: Unexpected token o error.  I also tried msg.payload[0].fanstatus but got an error on that one as well TypeError: Cannot read property 'fanstatus' of undefined


Adam S

unread,
May 18, 2015, 1:52:03 PM5/18/15
to node...@googlegroups.com
Turns out I was using the wrong values, after I set the websocket to send/recieve all messages I forgot to change the variables in the javascript.  So, I have everything working so far.

My next question is why when I click the Update button on the html page does it call the websocket anywhere from 3-10 times?  I have a debug node in that flow and every time I click the update button I would expect to see the debug text one time in the debug area in node red, instead it floods it.  What is up with that?

Dave C-J

unread,
May 18, 2015, 2:03:53 PM5/18/15
to node...@googlegroups.com
hmm, one step forward....

so ... either it is sending multiple times... or receiving multiple times...

suspecting the latter...
what happens if you stop and restart Node-RED totally ? (ie without re-deploys...)  is it better ?... 
(I'm wondering if we aren't cleaning up old connections on redeploy)

Adam S

unread,
May 18, 2015, 2:41:09 PM5/18/15
to node...@googlegroups.com
Full re-deploy did the trick, thanks!  I'm now noticing something else weird.  I have 2 web pages controlling the same gpio pin, one for mobile and one for desktop.  After I put in the mobile version (the flow this thread is about) the desktop page will no longer update the values and it was working fine with no changes before.  Whatever I last had the mobile page set to is what it always reverts the fan settings to.  Is there something in the background with websockets that constantly run?  Here is what I have in my flow:

[{"id":"8d3eeda3.29971","type":"websocket-listener","path":"/app","wholemsg":"true"},{"id":"e00a1942.7d2d4","type":"mqtt-broker","broker":"localhost","port":"1883","clientid":""},{"id":"b3bb40e2.2d92","type":"http in","name":"Temp Standard","url":"/temp","method":"get","x":83.5,"y":527,"z":"abafa038.54fa88","wires":[["61d29d3b.18a4cc"]]},{"id":"ca26a7dc.33f038","type":"http response","name":"Temp Standard","x":709.5,"y":527,"z":"abafa038.54fa88","wires":[]},{"id":"61d29d3b.18a4cc","type":"function","name":"Get Current Values","func":"msg.current = {\n    insidetemp: context.global.insidetemp,\n    outsidetemp: context.global.outsidetemp,\n    fanspeed: context.global.fanspeed,\n    fansdisabled: context.global.fansdisabled\n};\n\nif (context.global.fansdisabled == \"Disabled\"){\n    msg.dropdown = \"<select id=\\\"fan_status\\\"><option selected>Disabled</option><option>Auto</option><option>Manual</option></select>\";\n}\nif (context.global.fansdisabled == \"Auto\"){\n    msg.dropdown = \"<select id=\\\"fan_status\\\"><option>Disabled</option><option selected>Auto</option><option>Manual</option></select>\";\n}\nif (context.global.fansdisabled == \"Manual\"){\n    msg.dropdown = \"<select id=\\\"fan_status\\\"><option>Disabled</option><option>Auto</option><option selected>Manual</option></select>\";\n}\n\nreturn msg;","outputs":1,"valid":true,"x":288,"y":527,"z":"abafa038.54fa88","wires":[["76e37074.8e19a8"]]},{"id":"76e37074.8e19a8","type":"template","name":"","field":"payload","format":"handlebars","template":"<html>\n<head>\n</head>\n<body>\n    <form method=\"POST\" action=\"/disablefans\">\n        <p>Inside Temp: <input name=\"insidetemp\" value=\"{{current.insidetemp}}\"></p>\n        <p>Outside Temp: <input name=\"outsidetemp\" value=\"{{current.outsidetemp}}\"></p>\n        <p>Fan Speed: <input name=\"outsidetemp\" value=\"{{current.fanspeed}}%\"></p>\n        <p>Fan Status: {{{dropdown}}}</p>\n        <p><input type=\"range\" name=\"slider_1\" value=\"{{current.fanspeed}}\" min=\"0\" max=\"100\"  /></p>\n        <p><input type=\"submit\" value=\"Update Fan Status\"></p>\n    </form>\n    <form method=\"POST\" action=\"/updatetemp\">\n        <p><input type=\"submit\" value=\"Update Values\" onclick=\"history.go(0)\"></p>\n    </form>\n</body>\n</html>","x":525.5,"y":527,"z":"abafa038.54fa88","wires":[["ca26a7dc.33f038"]]},{"id":"b3231d0a.18df28","type":"function","name":"Set Values/Update Fan","func":"context.global.insidetemp = msg.payload * (9/5) + 32;\n\nif (context.global.fansdisabled == \"Auto\"){\n    if (context.global.insidetemp < 60){\n        context.global.fanspeed = 0;\n    }\n    if (context.global.insidetemp >= 60 && context.global.insidetemp < 68){\n        context.global.fanspeed = 15;\n    }\n    if (context.global.insidetemp >= 68 && context.global.insidetemp < 73){\n        context.global.fanspeed = 30;\n    }\n    if (context.global.insidetemp >= 73 && context.global.insidetemp < 77.5){\n        context.global.fanspeed = 40;\n    }\n    if (context.global.insidetemp >= 77.5 && context.global.insidetemp < 80){\n        context.global.fanspeed = 50;\n    }\n    if (context.global.insidetemp >= 80 && context.global.insidetemp < 82.5){\n        context.global.fanspeed = 60;\n    }\n    if (context.global.insidetemp >= 82.5 && context.global.insidetemp < 85){\n        context.global.fanspeed = 75;\n    }\n    if (context.global.insidetemp >= 85 && context.global.insidetemp < 87.5){\n        context.global.fanspeed = 90;\n    }\n    if (context.global.insidetemp >= 87.5){\n        context.global.fanspeed = 100;\n    }\n}\nif (context.global.fansdisabled == \"Disabled\"){\n    context.global.fanspeed = 0;\n}\n\nmsg.current = {\n    fanspeed: context.global.fanspeed,\n    insidetemp: context.global.insidetemp,\n    fanstatus: context.global.fansdisabled\n}\n\nmsg.payload = context.global.fanspeed;\n\nreturn msg;","outputs":1,"valid":true,"x":300,"y":339,"z":"abafa038.54fa88","wires":[["69a1289e.ec28c","c9b4cb6e.c568a8"]]},{"id":"177e6002.bff4e8","type":"ds18b20","name":"Shed Inisde","sensorid":"28-000006154ba3","timer":"1","x":74,"y":339,"z":"abafa038.54fa88","wires":[["b3231d0a.18df28"]]},{"id":"b647f4e6.6196f8","type":"debug","name":"","active":false,"console":"false","complete":"false","x":721,"y":271,"z":"abafa038.54fa88","wires":[]},{"id":"6d56f263.9f937c","type":"function","name":"Set Values","func":"var fahrenheit = msg.payload * (9/5) + 32;\n\ncontext.global.outsidetemp = fahrenheit;\n\nmsg.current = {\n    outsidetemp: context.global.outsidetemp\n}\n\nreturn msg;","outputs":1,"valid":true,"x":263,"y":406,"z":"abafa038.54fa88","wires":[["790f4fa7.5fe4f"]]},{"id":"16104bda.b13fdc","type":"ds18b20","name":"Shed Outside","sensorid":"28-000006155474","timer":"1","x":78,"y":406,"z":"abafa038.54fa88","wires":[["6d56f263.9f937c"]]},{"id":"b93bf43d.ad6c8","type":"debug","name":"","active":false,"console":"false","complete":"false","x":717,"y":470,"z":"abafa038.54fa88","wires":[]},{"id":"69a1289e.ec28c","type":"rpi-gpio out","name":"","pin":"22","set":"","level":"0","out":"pwm","x":542,"y":270,"z":"abafa038.54fa88","wires":[]},{"id":"c9b4cb6e.c568a8","type":"template","name":"","field":"payload","format":"handlebars","template":"Current fan speed: {{current.fanspeed}} Current inside temp: {{current.insidetemp}} Current fan status: {{current.fanstatus}}","x":532,"y":338,"z":"abafa038.54fa88","wires":[["b647f4e6.6196f8","be901cc1.2c2b1"]]},{"id":"790f4fa7.5fe4f","type":"template","name":"","field":"payload","format":"handlebars","template":"Current outside temp: {{current.outsidetemp}}","x":530,"y":406,"z":"abafa038.54fa88","wires":[["b93bf43d.ad6c8","996c686c.e78c58"]]},{"id":"be901cc1.2c2b1","type":"mqtt out","name":"","topic":"fans","qos":"","retain":"","broker":"e00a1942.7d2d4","x":738,"y":338,"z":"abafa038.54fa88","wires":[]},{"id":"996c686c.e78c58","type":"mqtt out","name":"","topic":"fans","qos":"","retain":"","broker":"e00a1942.7d2d4","x":736,"y":406,"z":"abafa038.54fa88","wires":[]},{"id":"7c376171.5b3758","type":"http in","name":"","url":"/disablefans","method":"post","x":95.5,"y":211,"z":"abafa038.54fa88","wires":[["cb0d7eb7.90fb98"]]},{"id":"9ee21763.3627f","type":"function","name":"Redirect back to /temp","func":"msg.res.redirect(\"/temp\");\n","outputs":"0","valid":true,"x":695,"y":211,"z":"abafa038.54fa88","wires":[]},{"id":"cb0d7eb7.90fb98","type":"function","name":"Set Values/Update Fan","func":"if (msg.payload.fan_status == \"Disabled\"){\n    msg.current = {\n        fanspeed: 0,\n        insidetemp: context.global.insidetemp\n    }\n    context.global.fanspeed = 0;\n    context.global.fansdisabled = \"Disabled\";\n}\n\nif (msg.payload.fan_status == \"Auto\"){\n    msg.current = {\n        fanspeed: context.global.fanspeed,\n        insidetemp: context.global.insidetemp\n    }\n    context.global.fansdisabled = \"Auto\";\n    \n    if (context.global.insidetemp < 60){\n        context.global.fanspeed = 0;\n    }\n    if (context.global.insidetemp >= 60 && context.global.insidetemp < 68){\n        context.global.fanspeed = 15;\n    }\n    if (context.global.insidetemp >= 68 && context.global.insidetemp < 72){\n        context.global.fanspeed = 30;\n    }\n    if (context.global.insidetemp >= 72 && context.global.insidetemp < 76.5){\n        context.global.fanspeed = 40;\n    }\n    if (context.global.insidetemp >= 76.5 && context.global.insidetemp < 80){\n        context.global.fanspeed = 50;\n    }\n    if (context.global.insidetemp >= 80 && context.global.insidetemp < 82.5){\n        context.global.fanspeed = 60;\n    }\n    if (context.global.insidetemp >= 82.5 && context.global.insidetemp < 85){\n        context.global.fanspeed = 75;\n    }\n    if (context.global.insidetemp >= 85 && context.global.insidetemp < 87.5){\n        context.global.fanspeed = 90;\n    }\n    if (context.global.insidetemp >= 87.5){\n        context.global.fanspeed = 100;\n    }\n}\n\nif (msg.payload.fan_status == \"Manual\"){\n    context.global.fansdisabled = \"Manual\";\n    context.global.fanspeed = msg.payload.slider_1;\n}\n\nmsg.payload = context.global.fanspeed;\n\nreturn msg;","outputs":1,"valid":true,"x":300,"y":211,"z":"abafa038.54fa88","wires":[["9ee21763.3627f","69a1289e.ec28c"]]},{"id":"dfc10029.7e1ec","type":"http in","name":"","url":"/updatetemp","method":"post","x":96.5,"y":89.88333129882812,"z":"abafa038.54fa88","wires":[["a56fe28c.7dd64"]]},{"id":"a56fe28c.7dd64","type":"function","name":"Redirect back to /temp","func":"msg.res.redirect(\"/temp\");\n","outputs":"0","valid":true,"x":696,"y":89.88333129882812,"z":"abafa038.54fa88","wires":[]},{"id":"f1a4f857.082b4","type":"inject","name":"","topic":"","payload":"Auto","payloadType":"string","repeat":"","crontab":"","once":true,"x":72.88333129882812,"y":34.883331298828125,"z":"abafa038.54fa88","wires":[["86d64d8.bc17cb"]]},{"id":"86d64d8.bc17cb","type":"function","name":"Redirect back to /temp","func":"context.global.fansdisabled = msg.payload;","outputs":"0","valid":true,"x":694.88330078125,"y":35.883331298828125,"z":"abafa038.54fa88","wires":[]},{"id":"fb35b8cb.7ff7d8","type":"websocket in","name":"app in","server":"8d3eeda3.29971","client":"","x":59.883331298828125,"y":149.88333129882812,"z":"abafa038.54fa88","wires":[["33c54437.d0f724"]]},{"id":"33c54437.d0f724","type":"function","name":"Kill Session","func":"msg._session=\"\";\n\nif (msg.fanstatus == \"Auto\"){\n    context.global.fansdisabled = \"Auto\";\n    if (context.global.insidetemp < 60){\n        context.global.fanspeed = 0;\n    }\n    if (context.global.insidetemp >= 60 && context.global.insidetemp < 68){\n        context.global.fanspeed = 15;\n    }\n    if (context.global.insidetemp >= 68 && context.global.insidetemp < 72){\n        context.global.fanspeed = 30;\n    }\n    if (context.global.insidetemp >= 72 && context.global.insidetemp < 76.5){\n        context.global.fanspeed = 40;\n    }\n    if (context.global.insidetemp >= 76.5 && context.global.insidetemp < 80){\n        context.global.fanspeed = 50;\n    }\n    if (context.global.insidetemp >= 80 && context.global.insidetemp < 82.5){\n        context.global.fanspeed = 60;\n    }\n    if (context.global.insidetemp >= 82.5 && context.global.insidetemp < 85){\n        context.global.fanspeed = 75;\n    }\n    if (context.global.insidetemp >= 85 && context.global.insidetemp < 87.5){\n        context.global.fanspeed = 90;\n    }\n    if (context.global.insidetemp >= 87.5){\n        context.global.fanspeed = 100;\n    }\n}\nif (msg.fanstatus == \"Disabled\"){\n    context.global.fansdisabled = \"Disabled\";\n    context.global.fanspeed = 0;\n}\nif (msg.fanstatus == \"Manual\"){\n    context.global.fansdisabled = \"Manual\";\n    context.global.fanspeed = msg.manualspeed;\n}\n\nmsg.current = {\n    insidetemp: context.global.insidetemp,\n    outsidetemp: context.global.outsidetemp,\n    fanspeed: context.global.fanspeed,\n    fansdisabled: context.global.fansdisabled\n};\n\nmsg.payload = context.global.fanspeed;\n\nreturn msg; ","outputs":1,"valid":true,"x":262.8833312988281,"y":149.88330078125,"z":"abafa038.54fa88","wires":[["c72d3fb3.2ee13","69a1289e.ec28c"]]},{"id":"c72d3fb3.2ee13","type":"websocket out","name":"app out","server":"8d3eeda3.29971","client":"","x":742.8833312988281,"y":149.88333129882812,"z":"abafa038.54fa88","wires":[]},{"id":"329c8209.e3ce4e","type":"http in","name":"Temp Mobile","url":"/tempmobile","method":"get","x":77,"y":593.88330078125,"z":"abafa038.54fa88","wires":[["80d6c2f1.442348"]]},{"id":"663e563.967f128","type":"http response","name":"Temp Mobile","x":720.9999694824219,"y":593.8832702636719,"z":"abafa038.54fa88","wires":[]},{"id":"7df06785.a18be8","type":"template","name":"","field":"payload","format":"handlebars","template":"<html>\n<head>\n\t<title>Simple Display</title>\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t<link rel=\"stylesheet\" href=\"http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css\">\n\t<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js\"></script>\n\t<script src=\"http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js\"></script>\n</head>\n<script type=\"text/javascript\">\n\tvar server = window.location.hostname;\n\tvar topics = {};\n\tvar wsUriC = \"ws://\"+server+\":1880/app\";\n\tvar ws;\n\tfunction wsConnectC() {\n\t\tconsole.log(\"connect\",wsUriC);\n\t\tws = new WebSocket(wsUriC);\n\t\tws.onmessage = function(msg) {\n\t\t\tconsole.log(msg.data);\n\t\t\tvar fromPage=JSON.parse(msg.data);\n\t\t\tif (fromPage.current.insidetemp) {\n\t\t        $(\"#insidetemp\").html(\"Inside Temp: \" + fromPage.current.insidetemp); \n            }\n            if (fromPage.current.outsidetemp) {\n\t\t        $(\"#outsidetemp\").html(\"Outside Temp: \" + fromPage.current.outsidetemp);\n            }\n            if (fromPage.current.fanstatus) {\n\t\t        +$(\"#fan_status\").val(fromPage.current.fansdisabled);\n            }\n            $(\"#fanspeed\").html(\"Fan Speed: \" + fromPage.current.fanspeed);\n            $(\"#slider_1\").val(fromPage.current.fanspeed);\n\t\t}\n\t\tws.onopen = function() {\n\t\t\t$(\"#status\").html(\"connected\");\n\t\t\tconsole.log(\"connected\");\n\t\t}\n\t\tws.onclose = function() {\n\t\t\t$(\"#status\").html(\"not connected\");\n\t\t\tsetTimeout(wsConnectC,1000);\n\t\t}\n\t}\n   \n\tfunction sendMessage(){\n\t\t// send message back to page in simple JSON format\n\t\t// example {\"part1\":\"Hello\",\"part2\":\"50\"}\n\t\tvar fanstatus=$(\"#fan_status\").val();\n\t\tvar speedslider=$(\"#slider_1\").val();\n\t\tvar jsontext = '{\"fanstatus\":\"' + fanstatus + '\", \"manualspeed\":\"' + speedslider + '\"}';//' + speedslider + '\n\t\tws.send(jsontext);\n\t} // end sendMessage\n\n</script>\n<body onload=\"wsConnectC();\" onunload=\"ws.disconnect;\">\n\t<div data-role=\"page\" id=\"one\">\n\t\t<div data-role=\"header\">\n\t\t\t<h1>Websockets Test Page</h1>\n\t\t</div>\n\t\t<div role=\"main\" class=\"ui-content\">\n\t\t\t<h1>Temperature Display</h1>\n\t\t\t<div id=\"status\">status unknown</div>\n\t\t\t<hr/>\n\t\t\t<div id=\"insidetemp\">Inside Temp: {{current.insidetemp}}</div>\n\t\t\t<div id=\"outsidetemp\">Outside Temp: {{current.outsidetemp}}</div>\n\t\t\t<div id=\"fanspeed\">Fan Speed: {{current.fanspeed}}</div>\n\t\t\t<div id=\"fanstatus\">Fan Status: {{{dropdown}}}</div>\n\t\t\t<hr/>\n\t\t\t<label for=\"slider_1\">Input slider:</label>\n\t\t\t<input type=\"range\" id=\"slider_1\" value={{current.fanspeed}} min=\"0\" max=\"100\"  />\n\t\t\t<input type=\"button\" value=\"Update\" onClick=\"sendMessage()\" />\n\t\t</div>\n\t</div>\n</body>\n</html>","x":526.5,"y":593.8832702636719,"z":"abafa038.54fa88","wires":[["663e563.967f128"]]},{"id":"80d6c2f1.442348","type":"function","name":"Get Current Values","func":"msg.current = {\n    insidetemp: context.global.insidetemp,\n    outsidetemp: context.global.outsidetemp,\n    fanspeed: context.global.fanspeed,\n    fansdisabled: context.global.fansdisabled\n};\n\nif (context.global.fansdisabled == \"Disabled\"){\n    msg.dropdown = \"<select id=\\\"fan_status\\\"><option selected>Disabled</option><option>Auto</option><option>Manual</option></select>\";\n}\nif (context.global.fansdisabled == \"Auto\"){\n    msg.dropdown = \"<select id=\\\"fan_status\\\"><option>Disabled</option><option selected>Auto</option><option>Manual</option></select>\";\n}\nif (context.global.fansdisabled == \"Manual\"){\n    msg.dropdown = \"<select id=\\\"fan_status\\\"><option>Disabled</option><option>Auto</option><option selected>Manual</option></select>\";\n}\n\nreturn msg;","outputs":1,"valid":true,"x":291,"y":593.8832702636719,"z":"abafa038.54fa88","wires":[["7df06785.a18be8"]]}]

Dave C-J

unread,
May 18, 2015, 3:13:08 PM5/18/15
to node...@googlegroups.com
Hi,

Not sure about that - but what the previous thing indicates is that we aren't closing the socket properly so I need to fix that anyway.

Adam S

unread,
May 20, 2015, 9:00:51 AM5/20/15
to node...@googlegroups.com
Not sure if it helps you or not, but I was getting that issue while using Modified Flows deploy.  The issue seemed to go away after I did a full deploy, so maybe it's just the modified deploys that need attention?

Adam S

unread,
May 20, 2015, 9:21:45 AM5/20/15
to node...@googlegroups.com
I also found the problem in my flow...stupid copy/paste error.  I copied the drop down text from my mobile page with an added option for manual and pasted it in to my desktop page, but for GET node to work the identifier for the HTML object has to be name, not id (opposite with my mobile page).  Everything works perfect now.

Adam S

unread,
May 20, 2015, 11:24:46 AM5/20/15
to node...@googlegroups.com
Here are my finished flows should anyone want to take a gander on how everything works:

[{"id":"423c7659.d90fe","type":"websocket-listener","path":"/ws/tempmobile","wholemsg":"true"},{"id":"e00a1942.7d2d4","type":"mqtt-broker","broker":"localhost","port":"1883","clientid":""},{"id":"b3bb40e2.2d92","type":"http in","name":"Standard Temp Web Page","url":"/temp","method":"get","x":136,"y":469,"z":"abafa038.54fa88","wires":[["61d29d3b.18a4cc"]]},{"id":"ca26a7dc.33f038","type":"http response","name":"Temp Standard Out","x":1051.5,"y":469,"z":"abafa038.54fa88","wires":[]},{"id":"61d29d3b.18a4cc","type":"function","name":"Get Current Values","func":"//Put values in JSON format\nmsg.current = {\n    insidetemp: context.global.insidetemp,\n    outsidetemp: context.global.outsidetemp,\n    fanspeed: context.global.fanspeed,\n    fansdisabled: context.global.fansdisabled\n};\n\n//Creat HTML for drop down menu\nif (context.global.fansdisabled == \"Disabled\"){\n    msg.dropdown = \"<select name=\\\"fan_status\\\"><option selected>Disabled</option><option>Auto</option><option>Manual</option></select>\";\n}\nif (context.global.fansdisabled == \"Auto\"){\n    msg.dropdown = \"<select name=\\\"fan_status\\\"><option>Disabled</option><option selected>Auto</option><option>Manual</option></select>\";\n}\nif (context.global.fansdisabled == \"Manual\"){\n    msg.dropdown = \"<select name=\\\"fan_status\\\"><option>Disabled</option><option>Auto</option><option selected>Manual</option></select>\";\n}\n\nreturn msg;","outputs":1,"valid":true,"x":384,"y":469,"z":"abafa038.54fa88","wires":[["76e37074.8e19a8"]]},{"id":"76e37074.8e19a8","type":"template","name":"Standard Temp HTML","field":"payload","format":"handlebars","template":"<html>\n<head>\n</head>\n<body>\n    <form method=\"POST\" action=\"/updatefan\">\n        <p>Inside Temp: <input name=\"insidetemp\" value=\"{{current.insidetemp}}\"></p>\n        <p>Outside Temp: <input name=\"outsidetemp\" value=\"{{current.outsidetemp}}\"></p>\n        <p>Fan Speed: <input name=\"fanspeed\" value=\"{{current.fanspeed}}%\"></p>\n        <p>Fan Status: {{{dropdown}}}</p>\n        <p><input type=\"range\" name=\"slider_1\" value=\"{{current.fanspeed}}\" min=\"0\" max=\"100\"  /></p>\n        <p><input type=\"submit\" value=\"Update Fan Status\"></p>\n    </form>\n    <form method=\"POST\" action=\"/updatetemp\">\n        <p><input type=\"submit\" value=\"Update Values\" onclick=\"history.go(0)\"></p>\n    </form>\n</body>\n</html>","x":696.5,"y":469,"z":"abafa038.54fa88","wires":[["ca26a7dc.33f038"]]},{"id":"b3231d0a.18df28","type":"function","name":"Set Values/Update Fan","func":"//Convert Celcius to Fahrenheit\ncontext.global.insidetemp = msg.payload * (9/5) + 32;\n\n//If fan status is auto set speed based on temp values\nif (context.global.fansdisabled == \"Auto\"){\n    if (context.global.insidetemp < 60){\n        context.global.fanspeed = 0;\n    }\n    if (context.global.insidetemp >= 60 && context.global.insidetemp < 68){\n        context.global.fanspeed = 15;\n    }\n    if (context.global.insidetemp >= 68 && context.global.insidetemp < 73){\n        context.global.fanspeed = 30;\n    }\n    if (context.global.insidetemp >= 73 && context.global.insidetemp < 77.5){\n        context.global.fanspeed = 40;\n    }\n    if (context.global.insidetemp >= 77.5 && context.global.insidetemp < 80){\n        context.global.fanspeed = 50;\n    }\n    if (context.global.insidetemp >= 80 && context.global.insidetemp < 82.5){\n        context.global.fanspeed = 60;\n    }\n    if (context.global.insidetemp >= 82.5 && context.global.insidetemp < 85){\n        context.global.fanspeed = 75;\n    }\n    if (context.global.insidetemp >= 85 && context.global.insidetemp < 87.5){\n        context.global.fanspeed = 90;\n    }\n    if (context.global.insidetemp >= 87.5){\n        context.global.fanspeed = 100;\n    }\n}\n\n//If fan status is disabled set speed to 0\nif (context.global.fansdisabled == \"Disabled\"){\n    context.global.fanspeed = 0;\n}\n\n//Put values in JSON format\nmsg.current = {\n    fanspeed: context.global.fanspeed,\n    insidetemp: context.global.insidetemp,\n    fanstatus: context.global.fansdisabled\n}\n\n//Set payload to fan speed to set PWM output on Pi\nmsg.payload = context.global.fanspeed;\n\nreturn msg;","outputs":1,"valid":true,"x":396,"y":339,"z":"abafa038.54fa88","wires":[["69a1289e.ec28c","c9b4cb6e.c568a8"]]},{"id":"177e6002.bff4e8","type":"ds18b20","name":"Shed Inisde","sensorid":"28-000006154ba3","timer":"1","x":92,"y":339,"z":"abafa038.54fa88","wires":[["b3231d0a.18df28"]]},{"id":"6d56f263.9f937c","type":"function","name":"Set Values","func":"//Convert Celcius to Fahrenheit\ncontext.global.outsidetemp = msg.payload * (9/5) + 32;\n\n//Put values in JSON format\nmsg.current = {\n    outsidetemp: context.global.outsidetemp\n}\n\nreturn msg;","outputs":1,"valid":true,"x":359,"y":406,"z":"abafa038.54fa88","wires":[["790f4fa7.5fe4f"]]},{"id":"16104bda.b13fdc","type":"ds18b20","name":"Shed Outside","sensorid":"28-000006155474","timer":"1","x":96,"y":406,"z":"abafa038.54fa88","wires":[["6d56f263.9f937c"]]},{"id":"69a1289e.ec28c","type":"rpi-gpio out","name":"","pin":"22","set":"","level":"0","out":"pwm","x":663,"y":270,"z":"abafa038.54fa88","wires":[]},{"id":"c9b4cb6e.c568a8","type":"template","name":"Set Mustache Values for Inside Temp","field":"payload","format":"handlebars","template":"Current fan speed: {{current.fanspeed}} Current inside temp: {{current.insidetemp}} Current fan status: {{current.fanstatus}}","x":750,"y":338,"z":"abafa038.54fa88","wires":[["be901cc1.2c2b1"]]},{"id":"790f4fa7.5fe4f","type":"template","name":"Set Mustache Values for Outside Temp","field":"payload","format":"handlebars","template":"Current outside temp: {{current.outsidetemp}}","x":755,"y":406,"z":"abafa038.54fa88","wires":[["996c686c.e78c58"]]},{"id":"be901cc1.2c2b1","type":"mqtt out","name":"","topic":"fans","qos":"","retain":"","broker":"e00a1942.7d2d4","x":1091,"y":338,"z":"abafa038.54fa88","wires":[]},{"id":"996c686c.e78c58","type":"mqtt out","name":"","topic":"fans","qos":"","retain":"","broker":"e00a1942.7d2d4","x":1090,"y":406,"z":"abafa038.54fa88","wires":[]},{"id":"7c376171.5b3758","type":"http in","name":"Update Fan and Values","url":"/updatefan","method":"post","x":128.5,"y":146,"z":"abafa038.54fa88","wires":[["cb0d7eb7.90fb98"]]},{"id":"9ee21763.3627f","type":"function","name":"Redirect back to /temp","func":"msg.res.redirect(\"/temp\");\n","outputs":"0","valid":true,"x":1041,"y":146,"z":"abafa038.54fa88","wires":[]},{"id":"cb0d7eb7.90fb98","type":"function","name":"Set Values/Update Fan","func":"//If fan status is auto set speed based on temp values\nif (msg.payload.fan_status == \"Auto\"){\n    msg.current = {\n        fanspeed: context.global.fanspeed,\n        insidetemp: context.global.insidetemp\n    }\n    context.global.fansdisabled = \"Auto\";\n    \n    if (context.global.insidetemp < 60){\n        context.global.fanspeed = 0;\n    }\n    if (context.global.insidetemp >= 60 && context.global.insidetemp < 68){\n        context.global.fanspeed = 15;\n    }\n    if (context.global.insidetemp >= 68 && context.global.insidetemp < 72){\n        context.global.fanspeed = 30;\n    }\n    if (context.global.insidetemp >= 72 && context.global.insidetemp < 76.5){\n        context.global.fanspeed = 40;\n    }\n    if (context.global.insidetemp >= 76.5 && context.global.insidetemp < 80){\n        context.global.fanspeed = 50;\n    }\n    if (context.global.insidetemp >= 80 && context.global.insidetemp < 82.5){\n        context.global.fanspeed = 60;\n    }\n    if (context.global.insidetemp >= 82.5 && context.global.insidetemp < 85){\n        context.global.fanspeed = 75;\n    }\n    if (context.global.insidetemp >= 85 && context.global.insidetemp < 87.5){\n        context.global.fanspeed = 90;\n    }\n    if (context.global.insidetemp >= 87.5){\n        context.global.fanspeed = 100;\n    }\n}\n\n//If fan status is disabled set speed to 0\nif (msg.payload.fan_status == \"Disabled\"){\n    msg.current = {\n        fanspeed: 0,\n        insidetemp: context.global.insidetemp\n    }\n    context.global.fanspeed = 0;\n    context.global.fansdisabled = \"Disabled\";\n}\n\n//if fan status is manual set to value of slider\nif (msg.payload.fan_status == \"Manual\"){\n    msg.current = {\n        fanspeed: msg.payload.slider_1,\n        insidetemp: context.global.insidetemp\n    }\n    context.global.fansdisabled = \"Manual\";\n    context.global.fanspeed = msg.payload.slider_1;\n}\n\n//Set payload to fan speed to set PWM output on Pi\nmsg.payload = context.global.fanspeed;\n\nreturn msg;","outputs":1,"valid":true,"x":396,"y":146,"z":"abafa038.54fa88","wires":[["9ee21763.3627f","69a1289e.ec28c"]]},{"id":"dfc10029.7e1ec","type":"http in","name":"Update Temp","url":"/updatetemp","method":"post","x":98.5,"y":89.88333129882812,"z":"abafa038.54fa88","wires":[["a56fe28c.7dd64"]]},{"id":"a56fe28c.7dd64","type":"function","name":"Redirect back to /temp","func":"msg.res.redirect(\"/temp\");\n","outputs":"0","valid":true,"x":1042,"y":89.88333129882812,"z":"abafa038.54fa88","wires":[]},{"id":"f1a4f857.082b4","type":"inject","name":"Inject Initial Fan Status","topic":"","payload":"Auto","payloadType":"string","repeat":"","crontab":"","once":true,"x":129,"y":34.883331298828125,"z":"abafa038.54fa88","wires":[["86d64d8.bc17cb"]]},{"id":"86d64d8.bc17cb","type":"function","name":"Set Global Variable","func":"context.global.fansdisabled = msg.payload;","outputs":"0","valid":true,"x":1053.88330078125,"y":35.883331298828125,"z":"abafa038.54fa88","wires":[]},{"id":"fb35b8cb.7ff7d8","type":"websocket in","name":"Temp Web Socket","server":"423c7659.d90fe","client":"","x":113.5,"y":209.88333129882812,"z":"abafa038.54fa88","wires":[["33c54437.d0f724"]]},{"id":"33c54437.d0f724","type":"function","name":"Set Values/Update Fan","func":"//Strip session so everyone sees the same page\nmsg._session=\"\";\n\n//If fan status is auto set speed based on temp values\nif (msg.fanstatus == \"Auto\"){\n    context.global.fansdisabled = \"Auto\";\n    if (context.global.insidetemp < 60){\n        context.global.fanspeed = 0;\n    }\n    if (context.global.insidetemp >= 60 && context.global.insidetemp < 68){\n        context.global.fanspeed = 15;\n    }\n    if (context.global.insidetemp >= 68 && context.global.insidetemp < 72){\n        context.global.fanspeed = 30;\n    }\n    if (context.global.insidetemp >= 72 && context.global.insidetemp < 76.5){\n        context.global.fanspeed = 40;\n    }\n    if (context.global.insidetemp >= 76.5 && context.global.insidetemp < 80){\n        context.global.fanspeed = 50;\n    }\n    if (context.global.insidetemp >= 80 && context.global.insidetemp < 82.5){\n        context.global.fanspeed = 60;\n    }\n    if (context.global.insidetemp >= 82.5 && context.global.insidetemp < 85){\n        context.global.fanspeed = 75;\n    }\n    if (context.global.insidetemp >= 85 && context.global.insidetemp < 87.5){\n        context.global.fanspeed = 90;\n    }\n    if (context.global.insidetemp >= 87.5){\n        context.global.fanspeed = 100;\n    }\n}\n\n//If fan status is disabled set speed to 0\nif (msg.fanstatus == \"Disabled\"){\n    context.global.fansdisabled = \"Disabled\";\n    context.global.fanspeed = 0;\n}\n\n//if fan status is manual set to value of slider\nif (msg.fanstatus == \"Manual\"){\n    context.global.fansdisabled = \"Manual\";\n    context.global.fanspeed = msg.manualspeed;\n}\n\n//Put values in JSON format\nmsg.current = {\n    insidetemp: context.global.insidetemp,\n    outsidetemp: context.global.outsidetemp,\n    fanspeed: context.global.fanspeed,\n    fansdisabled: context.global.fansdisabled\n};\n\n//Set payload to fan speed to set PWM output on Pi\nmsg.payload = context.global.fanspeed;\n\nreturn msg; ","outputs":1,"valid":true,"x":397.8833312988281,"y":209.88330078125,"z":"abafa038.54fa88","wires":[["c72d3fb3.2ee13","69a1289e.ec28c"]]},{"id":"c72d3fb3.2ee13","type":"websocket out","name":"Temp Web Socket Out","server":"423c7659.d90fe","client":"","x":1041.8833312988281,"y":209.88333129882812,"z":"abafa038.54fa88","wires":[]},{"id":"329c8209.e3ce4e","type":"http in","name":"Mobile Temp Web Page","url":"/tempmobile","method":"get","x":128,"y":535.88330078125,"z":"abafa038.54fa88","wires":[["80d6c2f1.442348"]]},{"id":"663e563.967f128","type":"http response","name":"Temp Mobile Out","x":1058.9999694824219,"y":535.8832702636719,"z":"abafa038.54fa88","wires":[]},{"id":"7df06785.a18be8","type":"template","name":"Mobile Temp HTML","field":"payload","format":"handlebars","template":"<html>\n<head>\n\t<title>QSV Fan Page</title>\n\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n\t<link rel=\"stylesheet\" href=\"http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.css\">\n\t<script src=\"http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js\"></script>\n\t<script src=\"http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js\"></script>\n</head>\n<script type=\"text/javascript\">\n\tvar server = window.location.hostname;\n\tvar topics = {};\n\tvar wsUriC = \"ws://\"+server+\":1880/ws/tempmobile\";\n\tvar ws;\n\t\n\tfunction wsConnectC() {\n\t\tconsole.log(\"connect\",wsUriC);\n\t\tws = new WebSocket(wsUriC);\n\t\t\n\t\t//Function that runs when a message is received\n\t\tws.onmessage = function(msg) {\n\t\t\tconsole.log(msg.data);\n\t\t\tvar fromPage=JSON.parse(msg.data);\n\t\t\tif (fromPage.current.insidetemp) {\n\t\t        $(\"#insidetemp\").html(\"Inside Temp: \" + fromPage.current.insidetemp); \n            }\n            if (fromPage.current.outsidetemp) {\n\t\t        $(\"#outsidetemp\").html(\"Outside Temp: \" + fromPage.current.outsidetemp);\n            }\n            if (fromPage.current.fanstatus) {\n\t\t        $(\"#fan_status\").val(fromPage.current.fansdisabled);\n            }\n            $(\"#fanspeed\").html(\"Fan Speed: \" + fromPage.current.fanspeed);\n            $(\"#slider_1\").val(fromPage.current.fanspeed);\n\t\t}\n\t\t//Function that runs on connect\n\t\tws.onopen = function() {\n\t\t\t$(\"#status\").html(\"Status: Connected\");\n\t\t\tconsole.log(\"connected\");\n\t\t}\n\t\t//Function that runs on close\n\t\tws.onclose = function() {\n\t\t\t$(\"#status\").html(\"Status: Not Connected\");\n\t\t\tsetTimeout(wsConnectC,1000);\n\t\t}\n\t}\n\t\n    //Function to send data to websocket\n\tfunction sendMessage(){\n\t\tvar fanstatus=$(\"#fan_status\").val();\n\t\tvar speedslider=$(\"#slider_1\").val();\n\t\tvar jsontext = '{\"fanstatus\":\"' + fanstatus + '\", \"manualspeed\":\"' + speedslider + '\"}';\n\t\t\n\t\tws.send(jsontext);\n\t}\n\n</script>\n<body onload=\"wsConnectC();\" onunload=\"ws.disconnect;\">\n\t<div data-role=\"page\" id=\"one\">\n\t\t<div data-role=\"header\">\n\t\t\t<h1>QSV Fan Page</h1>\n\t\t</div>\n\t\t<div role=\"main\" class=\"ui-content\">\n\t\t\t<h1>Temperature Display</h1>\n\t\t\t<hr/>\n\t\t\t<div id=\"status\">status unknown</div>\n\t\t\t<hr/>\n\t\t\t<div id=\"insidetemp\">Inside Temp: {{current.insidetemp}}</div>\n\t\t\t<div id=\"outsidetemp\">Outside Temp: {{current.outsidetemp}}</div>\n\t\t\t<div id=\"fanspeed\">Fan Speed: {{current.fanspeed}}</div>\n\t\t\t<div id=\"fanstatus\">Fan Status: {{{dropdown}}}</div>\n\t\t\t<label for=\"slider_1\">Input slider:</label>\n\t\t\t<input type=\"range\" id=\"slider_1\" value={{current.fanspeed}} min=\"0\" max=\"100\"  />\n\t\t\t<input type=\"button\" value=\"Update\" onClick=\"sendMessage()\" />\n\t\t</div>\n\t</div>\n</body>\n</html>","x":688.5,"y":535.8832702636719,"z":"abafa038.54fa88","wires":[["663e563.967f128"]]},{"id":"80d6c2f1.442348","type":"function","name":"Get Current Values","func":"//Put values in JSON format\nmsg.current = {\n    insidetemp: context.global.insidetemp,\n    outsidetemp: context.global.outsidetemp,\n    fanspeed: context.global.fanspeed,\n    fansdisabled: context.global.fansdisabled\n};\n\n//Creat HTML for drop down menu\nif (context.global.fansdisabled == \"Disabled\"){\n    msg.dropdown = \"<select id=\\\"fan_status\\\"><option selected>Disabled</option><option>Auto</option><option>Manual</option></select>\";\n}\nif (context.global.fansdisabled == \"Auto\"){\n    msg.dropdown = \"<select id=\\\"fan_status\\\"><option>Disabled</option><option selected>Auto</option><option>Manual</option></select>\";\n}\nif (context.global.fansdisabled == \"Manual\"){\n    msg.dropdown = \"<select id=\\\"fan_status\\\"><option>Disabled</option><option>Auto</option><option selected>Manual</option></select>\";\n}\n\nreturn msg;","outputs":1,"valid":true,"x":387,"y":535.8832702636719,"z":"abafa038.54fa88","wires":[["7df06785.a18be8"]]}]

Dave C-J

unread,
May 20, 2015, 11:48:20 AM5/20/15
to node...@googlegroups.com

You can add it to flows.node-red.org if you wish ☺

Mark Setrem

unread,
May 20, 2015, 12:13:01 PM5/20/15
to node...@googlegroups.com
Although it would better if you added it to http://flows.nodered.org :-)

Dave C-J

unread,
May 20, 2015, 5:06:21 PM5/20/15
to node...@googlegroups.com

Touché ! Indeed.

Reply all
Reply to author
Forward
0 new messages